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

2 回答 2

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 回答
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),至少在调试模式下,用于调试目的。或者,您可以声明基类的构造函数 destructor protected,以防止创建不完整的对象,或在基类不是多态的情况下尝试销毁派生对象

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

这个答案可能不是你想要的。它仅表明即使在基类中根本没有定义派生类成员,也可以在基类中调用派生类成员。但是要直接调用它而不进行任何转换,您仍然需要virtual函数。

于 2012-10-18T12:58:34.940 回答