这是我在learncpp.com上阅读本节时遇到的一个问题.我使用了这里列出的代码,然后对测试做了一些改动.
背景
虚拟继承创建对基类的公共引用,它具有两个效果.
首先,它消除了歧义,因为只创建了一个基础成员的副本(例如,向PoweredDevice添加print()函数并在main()中调用它否则会导致编译器错误).
其次,派生程度最高的类负责调用基础构造函数.如果其中一个中间类尝试在初始化列表中调用基本构造函数,则应忽略该调用.
问题
当我编译并运行代码时,它返回:
PoweredDevice: 3
PoweredDevice: 3
Scanner: 1
PoweredDevice: 3
Printer: 2
Run Code Online (Sandbox Code Playgroud)
它应该返回:
PoweredDevice: 3
Scanner: 1
Printer: 2
Run Code Online (Sandbox Code Playgroud)
当我使用GDB(7.11.1)执行执行时,它表明中间函数也通过初始化列表调用PoweredDevice - 但是应该忽略这些函数.PoweredDevice的这种多次初始化不会导致任何成员的歧义,但确实让我感到困扰,因为代码只执行一次时执行多次.对于更复杂的问题,我不习惯使用虚拟继承.
为什么这些中间类仍在初始化基础?这是我的编译器(gcc 5.4.0)的怪癖,还是我误解了虚拟继承的工作原理?
编辑:代码
#include <iostream>
using namespace std;
class PoweredDevice
{
public:
int m_nPower;
public:
PoweredDevice(int nPower)
:m_nPower {nPower}
{
cout << "PoweredDevice: "<<nPower<<endl;
}
void print() { cout<<"Print m_nPower: "<<m_nPower<<endl; }
};
class Scanner : public virtual PoweredDevice
{
public:
Scanner(int nScanner, int nPower)
: PoweredDevice(nPower) …Run Code Online (Sandbox Code Playgroud)