I know virtual inheritance is covered here before and before asking this question, I went through the detail of the virtual inheritance and went through the details of a similar problem like the followings:
multiple-diamond-inheritance-compiles-without-virtual-but-doesnt-with and why does GCC give me an error - final overrider
My problem is slightly different as I am not using pure virtual function and explicitly using virtual inheritance to have one unique base
class. The hierarchy is as follows:
base
/\
/ \
der1 der2
\ /
der3
I know about the dreadful diamond on the derivation issue, and that's why I am using virtual inheritance.
#include <iostream>
class base
{
public :
base()
{
std::cout<<"base()" << std::endl;
}
virtual void fun()
{
std::cout<<"base" << std::endl;
}
};
class der1: virtual public base
{
public :
void fun()
{
std::cout<<"der1" << std::endl;
}
};
class der2 : virtual public base
{
public :
void fun()
{
std::cout<<"der2" << std::endl;
}
};
class der3 : public der1,public der2
{
public :
/*void fun()
{
std::cout<<"der3" << std::endl;
}*/
//if I took out the comment and the function
//is defined it compiles fine as expected
};
int main()
{
base *p=new der3;
//used scope operation explicitly to avoid ambiguity
p->base::fun(); //here it complains about 'no unique final overrider for fun'
return 0;
}
My understanding is since I am using virtual inheritance, there should only be one instance of the base,
and using the scope operator, I can invoke without ambiguity the virtual fun
function. The function is not pure virtual. If I do leave an implementation on the der3
class it is giving me a compiler error:
error: no unique final override for ‘virtual void base::fun()’ in ‘der3’
I can see how this issue works (final overrider). But mine doesn't. Is it getting confused between base::fun
, der1::fun
and der2::fun
? Does the scope operator help in any way?
Any clue or help is appreciated. I am using g++ 4.6.3.
The most-derived class has to provide an implementation of the virtual functions in the virtual base class - otherwise how would it provide that base class interface, given the intermediate classes (i.e. your der1
and der2
) provide two alternatives already - which one should it call? You have to disambiguate the situation (i.e. with der3::fun()
).
Sure you're not actually calling der3::fun()
as you're explicitly requesting base::fun()
, but that doesn't mean the rules don't apply, any more than thinking you could instantiate an abstract class if you don't try to call the pure-virtual functions.... The program is ill-formed until the code ties off these loose ends.
Using the scope resolution operator to specify that you want to call base::fun
doesn't make the error go away because the program would be ill-formed even with an empty main()
. You simply are not allowed to have a situation in which a virtual function has more than one final overrider in any derived class that exists in your program.
Informally, just because trying to call p->fun()
would be ambiguous, the program is ill-formed even if you don't do it.
Note: This is in contrast to the situation you have with overloaded functions, in which potential ambiguity is allowed---perhaps even unavoidable---as long as you avoid a call that actually would be ambiguous. Why are the rules different? Basically it is because even constructing an object of type der3
cannot be done in a sensible way---which version of fun
should the vtable point to?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With