为什么我的覆盖方法没有被调用?

时间:2017-02-09 23:50:47

标签: c++ inheritance

可能是一个简单的问题。我注意到了一些类似的问题,但它们似乎都没有解决我的问题,因此我的帖子。

Base.h:

class Base
{
public:
    Base();

protected:
    virtual void Create() {}
};

Base.cpp:

Base::Base()
{
    Create();
}

Child.h:

class Child : public Base
{
protected:
    void Create() override;
};

Child.cpp:

void Child::Create()
{
    // Work happens here
}
当我创建Create时,会在Base而不是Child上调用

Child。为什么Create没有调用Child

3 个答案:

答案 0 :(得分:5)

当您从基类的ctor调用虚方法时,将调用基类的虚方法。这就是语言的定义方式。有这样的理由,如:

void Child::Show()
{
    // Work that requires data fields of derived class.
}

如果要从基类的ctor调用派生类中的ShowChild::Show将使用Child的数据字段,但派生类的ctor尚未调用。< / p>

还有其他相关点值得注意。想象:

class Base     // The class is abstract.
{
public:
    Base() { Show(); }

protected:
    virtual void Show() = 0;
};

class Child : public Base
{
protected:
    void Show() override { /* Some work */ }
};

在这种情况下,当您创建Child的任何实例时,程序将简单地崩溃,因为尚未实例化纯虚方法。这将在以后完成,当Child的ctor的隐藏部分将起作用时。 ctor的这个隐藏部分修改了对象的VMT(虚方法表)。类似的故事发生在一个复杂的物体被摧毁时。 VMT可以多次修改,具体取决于基类链的复杂性。

答案 1 :(得分:2)

物体是从头开始构建的 当您尝试从Create的构造函数中调用Base(以及其他成员函数)时,它会获取由给定静态类型提供的 right 定义,即是Base 换句话说,不要依赖构造函数中的虚拟成员函数。

答案 2 :(得分:2)

构造者很特别。当你在构造函数中时,派生类尚未构造,因此它实际上不存在 - 构造函数首先执行,第二个执行。您从基类构造函数调用的任何成员都将调用基类成员。