您可以轻松地从该类继承:
class Derived: public TimerEvent { ... };
但是,您不能在子类中覆盖HandleTimer并期望它可以工作:
TimerEvent *e = new Derived(); e->HandleTimer();
这是因为静态方法在vtable中没有条目,因此不能是虚拟的.但是,您可以使用"void*Arg"将指针传递给您的实例...类似于:
struct TimerEvent { virtual void handle(int fd, short event) = 0; static void HandleTimer(int fd, short event, void *arg) { ((TimerEvent *) arg)->handle(fd, event); } }; class Derived: public TimerEvent { virtual void handle(int fd, short event) { // whatever } };
这样,HandleTimer仍然可以在C函数中使用,只需确保始终将"真实"对象作为"void*Arg"传递.
您可以轻松地从该类继承:
class Derived: public TimerEvent { ... };
但是,您不能在子类中覆盖HandleTimer并期望它可以工作:
TimerEvent *e = new Derived(); e->HandleTimer();
这是因为静态方法在vtable中没有条目,因此不能是虚拟的.但是,您可以使用"void*Arg"将指针传递给您的实例...类似于:
struct TimerEvent { virtual void handle(int fd, short event) = 0; static void HandleTimer(int fd, short event, void *arg) { ((TimerEvent *) arg)->handle(fd, event); } }; class Derived: public TimerEvent { virtual void handle(int fd, short event) { // whatever } };
这样,HandleTimer仍然可以在C函数中使用,只需确保始终将"真实"对象作为"void*Arg"传递.
在某种程度上,traits模式允许您继承和重新定义静态方法.
首先从基类开始:
struct base { static void talk() { std::cout << "hello" << std::endl; } static void shout() { std::cout << "HELLO !!" << std::endl; } };
然后派生它并重新定义一些方法:
struct derived: public base { static void talk() { std::cout << "goodbye" << std::endl; } };
现在通过traits类调用方法:
template < class T > struct talker_traits { static void talk() { T::talk(); } static void shout() { T::shout(); } }; talker_traits::talk() // prints "hello" talker_traits ::shout() // prints "HELLO !!" talker_traits ::talk() // prints "goodbye" talker_traits ::shout() // prints "HELLO !!"
ideone演示
traits类可以重复使用的静态方法base::shout
,而"覆盖" base::talk
与derived::talk
.但是,实际继承有几个不同之处:
调用函数在编译时解析
子方法不需要与父方法具有相同的签名
它也适用于静态字段和typedef,最好的例子是std :: iterator_traits.