【问题标题】:Why is my override method not being called? [duplicate]为什么我的覆盖方法没有被调用? [复制]
【发布时间】:2017-06-28 04:39:42
【问题描述】:

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

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?

【问题讨论】:

标签: c++ inheritance


【解决方案1】:

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

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

如果您从基类的ctor调用派生类中的Show,Child::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 可以根据基类链的复杂程度进行多次修改。

【讨论】:

  • 我也很怀疑,但想确认一下。谢谢!
  • 您至少应该给出最明显的理由。孩子尚未完全实例化。
  • 我更新了我的帖子,你现在可以看到了。我打算这样做。
  • @KirillKobelev SDE 是什么意思?:)
  • 最有可能的 SDE 是指软件设计工程师。请问这里是最好的地方吗?
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 1970-01-01
      • 2015-06-18
      • 2020-05-12
      • 2010-11-29
      • 2016-03-07
      • 1970-01-01
      相关资源
      最近更新 更多