警告:基类‘A’在复制构造函数中应该明确初始化。

5

我有以下类结构:

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的复制构造函数调用B的复制构造函数,然后调用A的复制构造函数。为什么它要求我在D中调用A的复制构造函数呢?
如果我这样做,A的复制构造函数不会被调用两次吗?一次是从B调用的,一次是从D调用的。
非常感谢您对此的任何意见。

4
请展示你的真实测试用例。类定义以分号结束,并且你的构造函数不是真正的“private”。 - Lightness Races in Orbit
1
当我解决了那些问题,这段代码就可以编译:http://ideone.com/V3ygZ 所以你的问题可能出在你无效的C++代码和正确方法之间。在我们看到你实际使用的代码之前,我们不知道问题出在哪里。 - Lightness Races in Orbit
在修复了你的代码之后,我没有收到来自VC10和gcc的任何警告... - RoundPi
1
已经回答了吗?http://stackoverflow.com/q/4788695/1141095 - ezdazuzena
你使用的编译器是什么?当你在代码中修复分号和公共结构时,MingGw可以编译。 - L7ColWinters
显示剩余8条评论
3个回答

2
现在我确认我的判断是正确的,B使用虚拟继承从A派生而来。
当这种情况发生时,最终派生类负责构造基类。这允许多重继承中出现菱形继承问题。
======== A ============
   ^            ^
   B            C
    \           /
     \         /
      \       /
       \     /
          D

D继承自B和C,而B和C又都继承自A,因此D将从B和C各继承2个A的副本。

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

这就是为什么您会收到错误消息的原因。


1
D的复制构造函数调用B的复制构造函数,后者又调用A的复制构造函数。
不,它并没有。虚基类始终由正在构造的最派生类初始化。在成员初始化列表中为继承层次结构中的类进行初始化,但这些类不是正在构建对象的最派生类时,将被忽略。虚基类只能被初始化一次,规则是最派生类将显式地或隐式地执行此操作,如果基类未出现在使用的最派生类构造函数的成员初始化列表中,则会隐式执行此操作。
正如警告所提示的那样,对于复制构造函数,您几乎肯定要从被复制的对象中显式初始化虚基类。

0

原因在于虚继承。因此,A应该显式地进行初始化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接