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

Why is my override method not being called?

本文关键字:覆盖 方法 我的 调用 为什么      更新时间:2023-10-16

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

基数:

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

底座.cpp:

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

儿童:

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

儿童.cpp:

void Child::Create()
{
    // Work happens here
}

Create是在Base而不是Child上调用的,当我创建Child时。为什么不Create Child

从基类的 ctor 调用虚拟方法时,将调用基类的虚拟方法。这就是语言的定义方式。这是有原因的,例如:

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

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

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

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 可以根据基类链的复杂性进行多次修改。

构造函数很特殊。当您在构造函数中时,派生类尚未构造,因此它实际上不存在 - 构造函数首先执行 base,其次执行派生。从基类构造函数进行的任何成员调用都将是基类成员。

对象是从头开始构建的。
当您尝试从 Base 的构造函数中调用 Create(和其他成员函数(时,它会选取给定静态类型提供的正确定义,即 Base
换句话说,不要依赖于构造函数中的虚拟成员函数。