我已经通过将继承更改为虚拟继承解决了菱形继承(钻石问题)问题。
不幸的是,它破坏了我的构造函数。在其他情况下菱形继承(钻石问题)是个问题。
菱形的一侧:
TModuleBase -> TServerModuleBase -> MyModule
MyClass继承基类
class MyModule :
public TServerModuleBase
{
...
}
MyModule::MyModule()
: TServerModuleBase(ModuleName())
{
}
QString MyModule::ModuleName(void)
{
return "MyModuleName";
}
由于 TModuleBase 和 TServerMosuleBase 有两个可能的构造函数(区别:服务器不是公共(public)的而是 protected ):
class TModuleBase
{
public:
explicit TModuleBase(void);
explicit TModuleBase(QString moduleName);
}
class TServerModuleBase
: public virtual TModuleBase
{
protected:
explicit TServerModuleBase(void);
explicit TServerModuleBase(QString moduleName);
}
TServerModuleBase::TServerModuleBase(void)
: TModuleBase()
{
}
TServerModuleBase::TServerModuleBase(QString moduleName)
: TModuleBase(moduleName)
{
}
当调用 MyModule 构造函数时,它会调用无效的构造函数:
TServerModuleBase(ModuleName()) //expected
TServerModuleBase() //called
当我变回来
class TServerModuleBase
: public virtual TModuleBase
进入:
class TServerModuleBase
: public TModuleBase
构造函数选择按预期工作。
我正在使用 g++。是的,我做了干净的构建。很多次。
感谢您的关注、时间和帮助。
您需要从最派生的构造函数 (MyModule
) 调用虚基构造函数。 TServerModuleBase(QString)
ctor-initialiser 中的 TModuleBase(QString)
调用被忽略,然后它尝试默认构造 TModuleBase
在 MyModule
中(因为您没有显式调用它)。
当您从虚拟继承更改为普通继承时,TServerModuleBase()
会调用正确的构造函数(尽管它调用了两次,因为有两个基类拷贝)。
您需要在最派生的构造函数中调用基类构造函数的原因是因为在编译时基类的位置对于TServerModuleBase
是未知的,但对于MyModule 是已知的
。
我是一名优秀的程序员,十分优秀!