struct TimerEvent
{
event Event;
timeval TimeOut;
static void HandleTimer(int Fd, short Event, void *Arg);
};
HandleTimerは、Cライブラリ(libevent)に渡すため、静的である必要があります。
このクラスを継承したい。これはどのように行うことができますか?
ありがとう。
そのクラスから簡単に継承できます。
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
}
};
このようにして、C関数からHandleTimerを引き続き使用できます。必ず、「実際の」オブジェクトを常に「void * Arg」として渡すようにしてください。
ある程度の特性パターンにより、静的メソッドを継承および再定義できます。
まず、基本クラスから始めます。
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 !!"
トレイトクラスを使用すると、base::shout
をbase::talk
で「オーバーライド」しながら、静的メソッドderived::talk
を再利用できます。それでも、実際の継承にはいくつかの違いがあります。
静的フィールドとtypedefでも機能します。最も良い例は std :: iterator_traits です。
あなたの質問には、少し矛盾があります。 &TimerEvent::TimerHandler
をCライブラリに渡すと、まさにそのとおりになります。必要に応じて、&DerivedTimerEvent::TimerHandler
を渡すこともできます。ただし、&TimerEvent::TimerHandler
を渡してCライブラリ(!)で実際に&DerivedTimerEvent::TimerHandler
を意味していることを理解することはできません。