27
struct TimerEvent
{
   event Event;
   timeval TimeOut;
   static void HandleTimer(int Fd, short Event, void *Arg);
};

HandleTimer 需要是静态的,因为我将它传递给 C 库(libevent)。

我想从这个类继承。如何才能做到这一点?

谢谢。

4

3 回答 3

41

您可以轻松地从该类继承:

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”传递。

于 2009-02-05T12:49:59.087 回答
25

在某种程度上,特征模式允许您继承和重新定义静态方法。

首先从一个基类开始:

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

现在通过特征类调用方法:

template < class T >
struct talker_traits {
  static void talk() { T::talk(); }
  static void shout() { T::shout(); }
};

talker_traits<base>::talk()     // prints "hello"
talker_traits<base>::shout()    // prints "HELLO !!"

talker_traits<derived>::talk()  // prints "goodbye"
talker_traits<derived>::shout() // prints "HELLO !!"

ideone演示

base::shout特征类允许您在“覆盖”base::talk的同时重用静态方法derived::talk。尽管如此,实际继承还是有几个不同之处:

  • 调用的函数在编译时解析
  • 子方法不需要与父方法具有相同的签名

它也适用于静态字段和 typedef,最好的例子是std::iterator_traits

于 2015-06-12T07:11:58.257 回答
0

你的问题在这里有点冲突。当您传递&TimerEvent::TimerHandler给 C 库时,您就是这样做的。如果你愿意,你也可以通过&DerivedTimerEvent::TimerHandler。但是您不能通过&TimerEvent::TimerHandler并期望C 库(!)弄清楚您的实际意思是&DerivedTimerEvent::TimerHandler.

于 2009-02-06T09:58:09.247 回答