0

基本クラスのメンバー関数が子クラスのメンバー関数に直接アクセスできる可能性はありますか?

Androindのコードを見つけました。BufferQueueはBnSurfaceTexture継承し、1つのメンバー関数「requestBuffer」を持っています。

基本クラスBnSurfaceTextureでは、requestBufferを直接呼び出すだけであることがわかりました。

基本クラスBnSurfaceTextureは関数「requestBuffer」をどのように認識しますか?

ありがとう


基本クラスのメンバー関数:

status_t BnSurfaceTexture::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
        case REQUEST_BUFFER: {
            CHECK_INTERFACE(ISurfaceTexture, data, reply);
            int bufferIdx   = data.readInt32();
            sp<GraphicBuffer> buffer;
            /* it call requestBuffer directly */ <--------
            int result = requestBuffer(bufferIdx, &buffer);
            reply->writeInt32(buffer != 0);


子クラスの宣言と実装:

class BufferQueue : public BnSurfaceTexture {

private:
    virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);


status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
    ATRACE_CALL();
    ST_LOGV("requestBuffer: slot=%d", slot);
    Mutex::Autolock lock(mMutex);
    ...
    return NO_ERROR;
}
4

2 に答える 2

2

基本クラス関数が宣言されていること、および派生クラスが基本クラス関数定義の定義の前に定義されていることを確認してください。ここに例があります

#include <iostream>

class Base
{
    public :

    void call_derived ();
};

class Derived : public Base
{
    public :

    void derived_fun ()
    {
        std::cout << "Derived class member function called!" << std::endl;
    }
};

void Base::call_derived ()
{
    static_cast<Derived *>(this)->derived_fun();
}

int main ()
{
    Derived dobj;
    dobj.call_derived();

    return 0;
}

ただし、この使用は安全ではありません。不完全なオブジェクトstatic_castを試しても、コンパイラは文句を言いません。ただし、少なくともデバッグ モードでは、デバッグ目的でcall_derivedassertion を追加できます。assert(dynamic_cast<Derived *>(this)または、Base クラスのコンストラクタである destructor を宣言しprotectedて、不完全なオブジェクトの作成を防止したり、ベースがポリモーフィックでないときに派生オブジェクトを破棄しようとしたりすることもできます。

ただし、上記のコードは実際にはあまり一般的ではありません。static_castCRTP のように、関数を使用せずに静的ポリモーフィズムを使用および提供する、他のより高度な手法も存在しvirtualます。

この答えは、まさにあなたが望むものではないかもしれません。ベースでまったく定義されていなくても、ベースクラスで派生クラスメンバーを呼び出すことができることを示しているだけです。ただし、キャストせずに直接呼び出すには、まだvirtual関数が必要です。

于 2012-10-18T12:58:34.940 に答える
2

基本クラスの BnSurfaceTexture は関数 "requestBuffer" をどのように認識していますか?

この関数は、基本クラスで少なくとも宣言されている必要があり (既定の実装で定義されている可能性があります)、. である必要がありますvirtual

したがって、コンパイル時に、コンパイラはそのような関数が存在することを確認します。
関数呼び出しは実行時に解決されます。これがポリモーフィズムです。


小さな例:

class Base
{
public:
    virtual void f() { /* Base */ } // could be pure virtual
    virtual void g() { f(); };
};

class Derived: public Base
{
public:
    virtual void f() { /* derived */ }
};

あなたが持っているとき

Base* pB = new Derived;
pB->g();

g()呼び出しDerived::fます。

于 2012-10-18T11:50:32.053 に答える