1

I have resolved diamond inheritance with changing inheritance to virtual.

Unfortunately it breaks my constructor. Diamond inheritance is issue in other case.

One side of the diamond:

TModuleBase -> TServerModuleBase -> MyModule

MyClass inherits base class

 class MyModule : public TServerModuleBase { ... } MyModule::MyModule() : TServerModuleBase(ModuleName()) { } QString MyModule::ModuleName(void) { return "MyModuleName"; } 

Since TModuleBase and TServerMosuleBase have two possible constructors (difference: Servers are not public but 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) { } 

When MyModule constructors is called it calls invalid constructor:

 TServerModuleBase(ModuleName()) //expected TServerModuleBase() //called 

When I changeback

 class TServerModuleBase : public virtual TModuleBase 

into:

 class TServerModuleBase : public TModuleBase 

constructor selection works as expected.

I am using g++. And yes, I did clean build. Many times.

Thx for your attention, time and help.

0

1 Answer 1

1

You need to call the virtual base constructor from the most derived constructor (MyModule). The TModuleBase(QString) call in the TServerModuleBase(QString) ctor-initialiser is just ignored and then it tries to default construct TModuleBase in MyModule (because you didn't call it explicitly).

When you change from virtual inheritance to ordinary inheritance then TServerModuleBase() does call the proper constructor (albeit it calls it twice because there are two copies of the base).

The reason you need to call the base constructor in the most derived constructor is because at compile-time the location of the base class is not known to TServerModuleBase but it is known to MyModule.

Sign up to request clarification or add additional context in comments.

2 Comments

Why then keyword 'explicit' is ignored? I would expect that compiler would throw some error if constructor is not explicitly called.
@urkon explicit only applies when use copy-initialisation syntax like T x = 10. An explicit constructor would prevent this and force you to write T x(10). The keyword doesn't do anything for this case.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.