2012-10-18 183 views
0

基类成员函数可以直接访问子类成员函数吗?基类成员函数直接访问子类成员函数?

我找到的代码从Androind,所述BufferQueue继承BnSurfaceTexture,并且具有一个成员函数 “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; 
} 

回答

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;

+1

谢谢Kiril〜这正是我想知道的! –

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_derived一个不完整的对象编译器不会抱怨。但是,至少在调试模式下,您可以添加断言assert(dynamic_cast<Derived *>(this)以进行调试。或者,您可以声明基类的构造函数,析构函数protected,以防止创建不完整的对象,或尝试销毁派生对象,同时基不是多态的。还存在其他更先进的技术,如CRTP,它们也使用static_cast并提供不具有virtual功能的静态多态性。

这个答案可能不完全是你想要的。它只表明可以在基类中调用派生类成员,即使它没有在基类中定义。但要直接调用它,不需要任何投射,您仍然需要virtual函数。

+0

谢谢Yan〜虽然这不是我想要的完全答案。但它仍然是一个很好的伎俩。 –