Fre*_*ios 6 c++ inheritance templates virtual-functions
假设我们有一个继承的抽象Base类:
class Base
{
protected:
Base() {}
virtual ~Base() {}
virtual void on_event_foo(int) {}
virtual void on_event_bar(int) {}
};
struct Concrete : public Base
{
virtual void on_event_foo(int value) {/*do some stuff with @value*/}
};
Run Code Online (Sandbox Code Playgroud)
它是一种知道(在编译时是最好的)来覆盖virtual函数的方法Base(在构造函数中使用某些代码,或者使用特殊模式)?
我的目的是为使用一些回调的库实现一个包装器; 如果我能检查覆盖功能,我将只创建用户想要的回调.
我希望用户可以选择他想要覆盖的功能.然后在我的代码中,我将仅为重写的函数创建回调.纯virtual函数不是解决方案,因为它们不允许创建具体类而不会覆盖所有这些函数.
在目前的构造函数中Base,我连接了C API中的许多静态回调函数Base.在这些函数中,我调用相应的成员函数.例如,回调函数是static Base::EventFoo(/* ... */)内部调用object->on_event_foo(/* .. */).这是因为我不能将成员函数作为C库的回调.但是创建过多的回调会使我的包装更慢.所以,我想只连接用户想要的回调,即知道他所覆盖的功能.
如果您愿意更改一些内容,可以使用奇怪的重复模板模式来确定是否覆盖了该函数
#include <iostream>
template <class Derived>
struct Base
{
virtual void on_event() {}
void raise_event()
{
if (&Derived::on_event == &Base::on_event)
std::cout << "not overridden" << std::endl;
else
std::cout << "overridden" << std::endl;
}
};
struct Concrete1 : Base<Concrete1>
{
virtual void on_event() override {}
};
struct Concrete2 : Base<Concrete2>
{
// no override
};
int main()
{
Concrete1 c1;
Concrete2 c2;
c1.raise_event(); // prints overridden
c2.raise_event(); // prints not overridden
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该语句&Derived::on_event == &Base::on_event应该在编译时解决(如果这是你担心的),并且if可以优化掉.
虽然我同意其他人的意见,但这似乎是一种糟糕的模式.让基类具有像您已有的空事件处理程序会简单得多.