Reputation: 789
#include <iostream>
struct B1
{
virtual void method()=0;
virtual ~B1(){}
};
struct B2
{
virtual void method()=0;
virtual ~B2(){}
};
struct D: B1, B2
{
virtual void method()
{
std::cout << "D::method\n";
};
};
int main(int argc,char *argv[])
{
D d;
B1 &b1=d;
B2 &b2=d;
b1.method();
b2.method();
return 0;
}
Note, B1 and B2 do not share common interface.
Is it this legal? If yes - in which standard? C++98/03/11 ?
Both, msvc and gcc have compiled it OK.
Previously I thought, that I have to use some common interface for such case (possible virtual inheritence).
Does such situation have some special name?
How it works in details, please? Maybe some ISO references?
Upvotes: 13
Views: 6351
Reputation: 1315
afaik this is legal in every standart. i'm not sure if it has it's own special name, but it is similar to the diamond problem .
if you override "virtual void method()" in D, then you override both the method in B1 and B2.
Edit:
to anwser why you do not have "two different independed inherited virtual functions in D: B1::method and B2::method":
when overriding a method, you can can only specify the function name, return type and parameters, but you can not add signature details about which one you inherit from when overriding.
imagine that it would be possible, then it could look something like this:
struct D: B1, B2
{
virtual void B1::method()
{
std::cout << "D::method\n";
};
virtual void B2::method()
{
std::cout << "D::method\n";
};
};
but seeing this, you can already say that there is no possibility to have something like that, because when calling
objectD.method()
you can not specify which one you are calling. so even if there was a way to overload both, there is still the problem of distinguishing on the function call.
EDIT: "can not specify which one you are calling." refers to, you can not specify whether you want to call a class D overload of B2::method or the B2 method itself. objectD.B2::method will always invoke the B2 (not overloaded) method (which in this case won't compile as B2 has no implementation)
Upvotes: 1
Reputation: 354969
Your code is well-formed: void D::method()
overrides both void B1::method()
and void B2::method()
.
The specification states (C++11 §10.3/2):
If a virtual member function
vf
is declared in a classBase
and in a classDerived
, derived directly or indirectly fromBase
, a member functionvf
with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) asBase::vf
is declared, thenDerived::vf
is also virtual (whether or not it is so declared) and it overridesBase::vf
.
B1
declares a virtual member function void B1::method()
. Class D
is derived from B1
and it also declares a member function with the same name (method
), the same parameter list (no parameters), the same cv-qualification (no qualification) and the same ref-qualifier (no qualification).
Therefore, void D::method()
overrides void B1::method()
.
The same logic applies for void B2::method()
(just substitute B2
for B1
in the above explanation), so void D::method()
overrides both void B1::method()
and void B2::method()
.
Upvotes: 7