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

时间:2012-10-18 11:46:59

标签: android c++ inheritance virtual-functions

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

我发现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);


儿童类宣言&amp;实现:

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 个答案:

答案 0 :(得分: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 :(得分: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),至少在调试模式下,以进行调试。或者,您可以声明Base类的构造函数,析构函数protected,以防止创建不完整的对象,或者尝试在基础不是多态时销毁派生对象

但是,上述代码在现实世界中并不常见。存在其他更高级的技术,如CRTP,它也使用static_cast并提供没有virtual函数的静态多态性。

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