Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

HandleTimer needs to be static since I'm passing it to C library (libevent).

I want to inherit from this class. How can this be done?

Thanks.

like image 466
jackhab Avatar asked Feb 05 '09 12:02

jackhab


People also ask

Can static functions be inherited from base class?

static member functions act the same as non-static member functions: They inherit into the derived class. If you redefine a static member, all the other overloaded functions in the base class are hidden.

What does a derived class inherit from the base class?

The derived class inherits all members and member functions of a base class. The derived class can have more functionality with respect to the Base class and can easily access the Base class. A Derived class is also called a child class or subclass.

Can static class be inherited from base in C++?

Quick A: Yes, and there are no ambiguity with static members.

Can you inherit a static class?

Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor. However, they can contain a static constructor.


2 Answers

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".

like image 134
Joao da Silva Avatar answered Oct 14 '22 16:10

Joao da Silva


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.

like image 38
xavlours Avatar answered Oct 14 '22 15:10

xavlours