Virtual inheritance polymorphic call resolution
-
Hello,
This happens so rarely that I seem to have forgotten this and that. Suppose I have a diamond inheritance (virtual inheritance for base classes is provided), such as:class A { public: virtual void method(); }; class B : public virtual A { public: void method() override; }; class C : public virtual A { }; class D : public B, public C { };
I was wondering what happens if one calls a virtual function from the last derived class with the base pointer? As far as I can tell the call should be ambiguous, so am I required to provide an override in the last class of the hierarchy to resolve it? From the example above something along the lines:
class D : public B, public C { public: void method() override { B::method(); } };
-
Hello,
This happens so rarely that I seem to have forgotten this and that. Suppose I have a diamond inheritance (virtual inheritance for base classes is provided), such as:class A { public: virtual void method(); }; class B : public virtual A { public: void method() override; }; class C : public virtual A { }; class D : public B, public C { };
I was wondering what happens if one calls a virtual function from the last derived class with the base pointer? As far as I can tell the call should be ambiguous, so am I required to provide an override in the last class of the hierarchy to resolve it? From the example above something along the lines:
class D : public B, public C { public: void method() override { B::method(); } };
@kshegunov
Hi
It seems spot on.
My memory was even more vague about the diamond case so i consulted
http://www.cprogramming.com/tutorial/virtual_inheritance.html
and yes using virtual should be the solution.
But let's see if there are other opinions or solutions.
Being in C++ Gurus, ill just keep low profile ;) -
Ah yes, the famous problem deemed unsolvable by Java creators, and yet solved and working in c++ decades ago ;)
@kshegunov Draw it on a piece of paper. There's no diamond here. Just a triangle with a dangling A outside of it ;) Having that, you've got your virtuals wrong. The classes that inherit the same base (B) are C and D, so that's where you need the
virtual
keyword:class A { public: virtual void method(); }; class B : public A { public: void method() override; }; class C : public virtual B { }; class D : public virtual B, public C { public: void method() override { B::method(); } };
In the example you posted
B::method()
would be indeed ambiguous and as such - is invalid and won't compile. -
Ah yes, the famous problem deemed unsolvable by Java creators, and yet solved and working in c++ decades ago ;)
@kshegunov Draw it on a piece of paper. There's no diamond here. Just a triangle with a dangling A outside of it ;) Having that, you've got your virtuals wrong. The classes that inherit the same base (B) are C and D, so that's where you need the
virtual
keyword:class A { public: virtual void method(); }; class B : public A { public: void method() override; }; class C : public virtual B { }; class D : public virtual B, public C { public: void method() override { B::method(); } };
In the example you posted
B::method()
would be indeed ambiguous and as such - is invalid and won't compile.There's a typo, Chris,
C
should derive fromA
and it is a diamond.
Read as:class C : public virtual A
PS. Corrected in the original post.
-
There's a typo, Chris,
C
should derive fromA
and it is a diamond.
Read as:class C : public virtual A
PS. Corrected in the original post.
Oh, ok, then your original solution was indeed correct.
-
Oh, ok, then your original solution was indeed correct.
Okay. Thanks!
1/6