首页 > 解决方案 > 派生的模板类不调用构造函数

问题描述

我正在用 C++ 实现一个事件模板,如下所示

模板.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();
    }
};

事件.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");
    }
};

然后我打电话E_Event::Get()访问E_Event. 但这里是日志:

Event()

我使用 arm-oe-linux-gnueabi-g++ (gcc 版本 6.4.0 (GCC))

为什么E_Event不调用构造函数?

标签: c++templatessingleton

解决方案


您观察到的并不是从构造函数调用虚函数的结果。

在构造函数中,虚拟调用机制被禁用,因为尚未发生从派生类的覆盖。对象是从基础向上构建的,“在派生之前的基础”。

这意味着当您Init()E_Event的构造函数调用时,最新的“最新”覆盖版本Init()是基类的Event

但是,在您的情况下,不会发生Init()来自构造函数的调用。E_Event

构造派生类时,还会构造基类的实例。考虑这个简单的例子。

#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();
}

输出将是

Base constructor
Derived constructor

如您所见,Base也调用了的构造函数。所以从E_Event的构造函数中也调用了,它已经抛出了异常,这就是为什么不会调用Event()任何将在其中的原因。E_Event


推荐阅读