2012-10-18 4 views
0

Est-il possible que la fonction membre de la classe de base puisse accéder directement à la fonction de membre de la classe enfant?La fonction membre de la classe de base accède directement à la fonction membre de la classe enfant?

Je trouve le code de Androind, le BufferQueue hérite BnSurfaceTexture, et a une fonction membre "requestBuffer".

Dans la classe de base BnSurfaceTexture, j'ai trouvé qu'il suffit d'appeler requestBuffer directement.

Comment la classe de base BnSurfaceTexture connait-elle la fonction "requestBuffer"?

Merci


La fonction de membre de classe de base:

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); 


La déclaration de classe enfant & mise en œuvre:

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; 
} 

Répondre

2

Comment la classe de base BnSurfaceTexture connaît-elle la fonction "requestBuffer"?

Cette fonction doit avoir été au moins déclarée (il aurait pu être défini avec une implémentation par défaut) dans la classe de base et il doit être virtual. Ainsi, lors de la compilation, le compilateur voit qu'une telle fonction existe.
L'appel de fonction est résolu au moment de l'exécution. C'est le polymorphisme.


petit exemple:

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

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

Lorsque vous avez

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

g() appellera Derived::f;

+1

Merci Kiril ~ c'est exactement ce que je veux savoir !! –

2

Assurez-vous que la fonction de la classe de base est déclarée , et la classe dérivée est définir avant définition de la fonction de la classe de base définition. Voici un exemple

#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; 
} 

Cependant, cette utilisation de static_cast est dangereux, le compilateur ne se plaindra pas si vous essayez call_derived sur un objet incomplet. Toutefois, vous pouvez ajouter une assertion assert(dynamic_cast<Derived *>(this), au moins en mode débogage, à des fins de débogage.Alternativement, vous pouvez déclarer constructeur de la classe de base, destructeur protected, pour empêcher la création d'objet incomplet, ou tenter de détruire un objet dérivé alors que la base n'est pas polymorphe

Cependant, le code ci-dessus n'est pas vraiment commun dans le monde réel. D'autres techniques plus avancées existent, comme CRTP, qui utilisent également static_cast et fournissent un polymorphisme statique sans fonctions virtual.

Cette réponse peut ne pas être exactement ce que vous voulez. Cela montre seulement qu'il est possible d'appeler des membres de classe dérivés dans la classe de base même si elle n'est pas du tout définie dans la base. Mais pour l'appeler directement sans aucune distribution, vous avez toujours besoin des fonctions virtual.

+0

Merci Yan ~ Bien que ce n'est pas exactement la réponse que je veux. Mais c'est toujours une bonne astuce. –

Questions connexes