How can Derived class inherit a static function from Base class?

前端 未结 3 1253
旧巷少年郎
旧巷少年郎 2020-12-08 15:02
struct TimerEvent
{
   event Event;
   timeval TimeOut;
   static void HandleTimer(int Fd, short Event, void *Arg);
};

HandleTimer needs to be stat

相关标签:
3条回答
  • 2020-12-08 15:21

    You can easily inherit from that class:

    class Derived: public TimerEvent {
        ...
    };
    

    However, you can't override HandleTimer in your subclass and expect this to work:

    TimerEvent *e = new Derived();
    e->HandleTimer();
    

    This is because static methods don't have an entry in the vtable, and can't thus be virtual. You can however use the "void* Arg" to pass a pointer to your instance... something like:

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

    This way, HandleTimer can still be used from C functions, just make sure to always pass the "real" object as the "void* Arg".

    0 讨论(0)
  • 2020-12-08 15:23

    To some extent the traits pattern lets you inherit and redefine static methods.

    First start with a base class:

    struct base {
      static void talk()  { std::cout << "hello" << std::endl; }
      static void shout() { std::cout << "HELLO !!" << std::endl; }
    };
    

    Then derive it and redefine some methods:

    struct derived: public base {
      static void talk()  { std::cout << "goodbye" << std::endl; }
    };
    

    And now call the methods via a traits class:

    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 demo

    The traits class lets you reuse the static method base::shout while "overriding" base::talk with derived::talk. Still, there are several difference with actual inheritance:

    • The function to call is resolved at compile time
    • The child method needs not have the same signature as the parent one

    It works with static fields and typedefs too, the best example is std::iterator_traits.

    0 讨论(0)
  • 2020-12-08 15:35

    You've got a bit of a conflict here in your question. When you pass &TimerEvent::TimerHandler to a C library, you do exactly that. You could also have passed &DerivedTimerEvent::TimerHandler, if you wanted. But you can't pass &TimerEvent::TimerHandler and expect the C library (!) to figure out you actually meant &DerivedTimerEvent::TimerHandler.

    0 讨论(0)
提交回复
热议问题