Derived of template class not calling constructor

Viewed 118

I'm implementing a Event template with C++ as below

Template.h

template<typename EventArg>
class Event {
public:
    typedef void (*EventHandle)(const EventArg&);
    vector<EventHandle> EventHandles;


protected:
    virtual void Init() { throw EventNotInitialized();};
    Event() 
    {
        printf("Event() \n");
        Init();
    }
};

Event.h

struct E_EventArgs {
    string data;
};
class E_Event : public Event<E_EventArgs>
{
public:
    static E_Event * Get() {
        static auto ins = new E_Event();
        return ins;
    }
protected:
    void Init() override {
        printf("E_Event() Init() \n");
    }
    E_Event() {
        Init();
        printf("E_Event() \n");
    }
};

Then I call E_Event::Get() to access to E_Event. But Here is the log:

Event()

I using arm-oe-linux-gnueabi-g++ (gcc version 6.4.0 (GCC))

Why constructor of E_Event is not called?

1 Answers

What you observe is not much of a consequence of calling a virtual function from a constructor.

In a constructor, the virtual call mechanism is disabled because overriding from derived classes hasn’t yet happened. Objects are constructed from the base up, “base before derived”.

Which means when you call Init() from E_Event's constructor, the most "recent" overridden version of Init() is of the base class Event.

However in your case the Init() call from E_Event's constructor doesn't happen.

When you construct a derived class, an instance of base class is also constructed. Consider this simple example.

#include <iostream>
class Base
{
public:
    Base()
    {
        std::cout<<"Base constructor"<<std::endl;
    }
};
class Derived: public Base
{
public:
    Derived()
    {
        std::cout<<"Derived constructor";
    }
};
int main()
{
  Derived();
}

The output will be

Base constructor
Derived constructor

As you can see, the constructor of Base is also called. So from E_Event's constructor the Event() is also called, which already throws exception, that's why whatever will be in E_Event won't be called.

Related