Noa*_*ahR 8 c++ member-function-pointers
与虚拟成员函数相反,我需要一种解决方案,其中可以注册在每个级别类派生中实现的函数,以便稍后由基类调用.(不仅仅是最衍生的实现)
为此,我正在考虑为派生类提供一种机制,以便在基类中注册它们的函数,例如在派生类构造函数中.
我遇到了成员函数指针参数的问题.我以为Derived是从Base派生的,this指针应该自动生成.
这可以接近我正在尝试或我需要使用静态成员函数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 ) {};
}
Run Code Online (Sandbox Code Playgroud)
编译错误:
error: no matching function for call to 'Derived::registerPrepFn(void (Derived::*)(int))'
note: candidates are: 'void Base::registerPrepFn(void (Base::*)(int))'
Run Code Online (Sandbox Code Playgroud)
jpa*_*cek 12
如果您只需要击败错误消息,那么转换将执行:
class Derived : public Base
{
Derived() {
registerPrepFn( static_cast<PrepFn>(&Derived::derivedPrepFn) );
};
void derivedPrepFn( int n ) {};
}
Run Code Online (Sandbox Code Playgroud)
通常使用a调用它Base* p(假设它实际上指向Derived):(p->*registered)(0)
有关工作示例,请参见http://ideone.com/BB9oy.
这种模式可以用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) {}
};
Run Code Online (Sandbox Code Playgroud)
根据我的口味, 的版本Derived2甚至更好,因为您将注册推入基类。通过删除默认Base构造函数(此处不能这样做,会破坏Derived),您可以强制派生类提供具有正确签名的指向成员函数的指针。