【问题标题】:The base class member function access child class member function directly?基类成员函数直接访问子类成员函数?
【发布时间】:2012-10-08 20:46:51
【问题描述】:

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

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

【问题讨论】:

    标签: android c++ inheritance virtual-functions


    【解决方案1】:

    基类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

    【讨论】:

    • 谢谢 Kiril ~ 这正是我想知道的!!
    【解决方案2】:

    只要确定基类函数声明,派生类define before定义基类函数definition。这是一个例子

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

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

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

    【讨论】:

    • 谢谢严〜虽然这不是我想要的确切答案。但这仍然是一个不错的技巧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    • 2021-03-25
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2017-09-19
    • 1970-01-01
    相关资源
    最近更新 更多