繁体   English   中英

如何注册派生的 class 成员 function 指针与基数 class

[英]How to register a derived class member function pointer with a base class

与虚拟成员函数相反,我需要一个解决方案,其中可以注册在每个级别 class 派生中实现的 function,以便稍后由基 class 调用。(不仅仅是最派生的实现)

为此,我正在考虑为派生类提供一种机制,以便在派生的 class 构造函数中将其 function 注册到基类 class 中。

不过,我在使用成员 function 指针参数时遇到了问题。 我在想 Derived 是从 Base 派生的,应该自动转换this指针。

这可以接近我正在尝试的方式来完成,还是我需要使用 static 成员函数、 void *static_cast

class Base
{
protected:
    typedef void (Base::*PrepFn)( int n );
    void registerPrepFn( PrepFn fn ) {};
}

class Derived : public Base
{
    Derived() {
        registerPrepFn( &Derived::derivedPrepFn );
    };

    void derivedPrepFn( int n ) {};

}

编译器错误:

error: no matching function for call to 'Derived::registerPrepFn(void (Derived::*)(int))'
note: candidates are:                 'void Base::registerPrepFn(void (Base::*)(int))'

如果您所需要的只是击败错误消息,那么转换将执行:

class Derived : public Base
{
    Derived() {
        registerPrepFn( static_cast<PrepFn>(&Derived::derivedPrepFn) );
    };

    void derivedPrepFn( int n ) {};

}

通常使用Base* p调用它(前提是它实际上指向 Derived ): (p->*registered)(0)

有关工作示例,请参见http://ideone.com/BB9oy

oop 不允许这样做。行为切换是通过在 object 创建时间多态对象的 class 来完成的。

如果您需要对象创建后的行为切换,您可以将动态行为重构为另一组多态类,并持有一个指向具有正确行为的 class 实例的“指针”。 请谷歌“装饰类”软件模式。

这种模式可以用Curiously Recurring Template Pattern来处理,即编译时多态性。

下面的代码无需强制转换即可编译。

template <class D>
class Base {
    protected:
        typedef void (D::*PrepFn) (int n);
        void registerPrepFn(PrepFn fn) {}
        Base() {};
        Base(PrepFn fn) {
            registerPrepFn(fn);
        }
};

class Derived : public Base<Derived>{
    Derived() {
        registerPrepFn( &Derived::derivedPrepFn);
    }
    void derivedPrepFn( int n) {};
};

class Derived2 : public Base<Derived2> {
    Derived2() : Base(&Derived2::derived2PrepFn) {}
    void derived2PrepFn(int n) {}
};

根据我的口味,带有Derived2的版本甚至更好,因为您将注册推送到基 class。通过删除默认的Base构造函数(这里不能这样做,会破坏Derived ),您可以强制派生类提供一个指针- 具有正确签名的成员 function。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM