C++ 虚拟继承中断初始化列表显式构造函数调用
我已通过将继承更改为虚拟来解决菱形继承问题 不幸的是,它破坏了我的构造函数。 钻石继承是另一种情况下的问题 钻石的一面: TModuleBase->TServerModuleBase->MyModule MyClass继承基类C++ 虚拟继承中断初始化列表显式构造函数调用,c++,inheritance,constructor,C++,Inheritance,Constructor,我已通过将继承更改为虚拟来解决菱形继承问题 不幸的是,它破坏了我的构造函数。 钻石继承是另一种情况下的问题 钻石的一面: TModuleBase->TServerModuleBase->MyModule MyClass继承基类 class MyModule : public TServerModuleBase { ... } MyModule::MyModule() : TServerModuleBase(M
class MyModule :
public TServerModuleBase
{
...
}
MyModule::MyModule()
: TServerModuleBase(ModuleName())
{
}
QString MyModule::ModuleName(void)
{
return "MyModuleName";
}
由于TModuleBase和TServerMosuleBase有两个可能的构造函数(区别:服务器不是公共的,而是受保护的):
调用MyModule构造函数时,会调用无效构造函数:
TServerModuleBase(ModuleName()) //expected
TServerModuleBase() //called
当我回头的时候
class TServerModuleBase
: public virtual TModuleBase
进入:
class TServerModuleBase
: public TModuleBase
构造函数选择按预期工作
我使用的是g++。是的,我做了干净的建筑。很多次
谢谢你的关注、时间和帮助 您需要从最派生的构造函数(
MyModule
)调用虚拟基构造函数。TServerModuleBase(QString)
ctor初始化器中的TModuleBase(QString)
调用被忽略,然后它尝试在MyModule
中默认构造TModuleBase
(因为您没有显式调用它)
当您从虚拟继承更改为普通继承时,TServerModuleBase()
确实调用了正确的构造函数(尽管它调用了两次,因为有两个基的副本)
您需要在最派生的构造函数中调用基类构造函数的原因是,在编译时,
TServerModuleBase
不知道基类的位置,但MyModule
知道基类的位置。您需要从最派生的构造函数中调用虚拟基类构造函数(MyModule
)。TServerModuleBase(QString)
ctor初始化器中的TModuleBase(QString)
调用被忽略,然后它尝试在MyModule
中默认构造TModuleBase
(因为您没有显式调用它)
当您从虚拟继承更改为普通继承时,TServerModuleBase()
确实调用了正确的构造函数(尽管它调用了两次,因为有两个基的副本)
您需要在最派生的构造函数中调用基类构造函数的原因是,在编译时,
TServerModuleBase
不知道基类的位置,但是MyModule
知道基类的位置,那么为什么忽略关键字explicit呢?如果未显式调用构造函数,我希望编译器会抛出一些错误。@urkonexplicit
仅在使用复制初始化语法(如tx=10
)时适用。一个显式的构造函数会阻止这种情况,并迫使您编写tx(10)
。关键字对这种情况没有任何作用。为什么忽略关键字“explicit”?如果未显式调用构造函数,我希望编译器会抛出一些错误。@urkonexplicit
仅在使用复制初始化语法(如tx=10
)时适用。一个显式的构造函数会阻止这种情况,并迫使您编写tx(10)
。关键字对本例没有任何作用。
class TServerModuleBase
: public TModuleBase