【问题标题】:warning: base class ‘A’ should be explicitly initialized in the copy constructor警告:应在复制构造函数中显式初始化基类“A”
【发布时间】:2012-02-24 07:40:01
【问题描述】:

我有以下类结构:

class A{
   A(){}
   A(const A& src){}
};

class B : virtual A {
   B():A(){}
   B(const B& src):A(src){}
};

class C : virtual A {
   C():A(){}
   C(const C& src):A(src){}
};
class D : virtual B, virtual C {
   D():B(),C(){}
   D(const D& src):B(src),C(src){}
};

这给了我警告:

在复制构造函数“D”中:

警告:基类“A”应在副本中显式初始化 构造函数

我不明白。 D 的 Copy -Constructor 调用 B 的 copy-ctor 调用 A 的 copy-ctor。 为什么它要我在D中调用A的copy-ctor

如果我这样做,A的copy-ctor不会被调用两次吗?一次从 B 调用,一次从 D 调用。

非常感谢您对此的任何意见。

【问题讨论】:

  • 它永远不会被调用两次。但我也不是很明白。
  • 展示你的真实测试用例。类定义以分号结尾,而你的构造函数不是真的 private.
  • 当我解决这些问题时,sn-p 编译:ideone.com/V3ygZ 所以你的问题在你的无效 C++ 和正确方法之间。在我们看到您实际使用的代码之前,我们不知道在哪里。
  • 修复代码后,我没有收到来自 VC10 和 gcc 的任何警告...
  • 已经回答了吗? stackoverflow.com/q/4788695/1141095

标签: c++ inheritance copy-constructor


【解决方案1】:

现在我已经确认我是对的,B 使用虚拟继承从 A 派生。

当这种情况发生时,最派生类负责构建基类。这允许多继承菱形。

======== A ============
   ^            ^
   B            C
    \           /
     \         /
      \       /
       \     /
          D

D 派生自 B 和 C,并且都派生自 A,因此 D 将继承 A 的 2 个副本,一个来自 B,一个来自 C。

如果 B1 和 B2 都使用虚继承从 A 派生,那么最终类必须初始化基类,即 A,从而确保只有一次实例。

这就是您收到错误消息的原因。

【讨论】:

    【解决方案2】:

    D 的 Copy-Constructor 调用 B 的 copy-ctor 调用 A 的 copy-ctor。

    不,它没有。虚拟基类总是由正在构造的最派生类初始化。继承层次结构中的类的成员初始化器列表中的初始化被忽略,这些初始化不是正在构建的对象的最派生类。虚拟基类只能初始化一次,规则是如果基类未出现在使用的最派生类构造函数的成员初始化器列表中,则最派生类将显式或隐式执行此操作。

    作为警告提示,对于复制构造函数,您几乎肯定希望从被复制的对象中显式初始化虚拟基类。

    【讨论】:

      【解决方案3】:

      原因是虚拟继承。因此 A 应该被显式初始化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-24
        • 2014-07-02
        • 2015-10-24
        • 1970-01-01
        • 1970-01-01
        • 2012-08-16
        相关资源
        最近更新 更多