I've just tried this piece of code:
struct FaceOfPast
{
virtual void Smile() = 0;
};
struct FaceOfFuture
{
virtual void Smile() = 0;
};
struct Janus : public FaceOfPast, public FaceOfFuture
{
virtual void Smile() {printf(":) ");}
};
...
void main()
{
Janus* j = new Janus();
FaceOfFuture* future = j;
FaceOfPast* past = j;
future->Smile();
past->Smile();
delete j;
}
It works as intended (outputs two smiley faces), but I don't think it should even compile, redeclaration of Smile()
in Janus
being ambiguous.
How (and why) does it work?
There's no ambiguity because you call Smile()
on pointers to FaceOfFuture
and FaceOfPast
that only declare one method Smile()
.
Because calling the method on a base class pointer can't result in an ambiguity, let's treat the situations when you call the method directly on the child class pointer:
Janus* j = new Janus();
j->Smile();
The derived class, besides overriding, also hides the base classes' declaration of Smile()
. You'd have an ambiguity only if you wouldn't be overriding the method in your derived class:
The following compiles:
struct FaceOfPast
{
virtual void Smile() {printf(":) ");}
};
struct FaceOfFuture
{
virtual void Smile() {printf(":) ");}
};
struct Janus : public FaceOfPast, public FaceOfFuture
{
virtual void Smile() {printf(":) ");}
};
int main()
{
Janus* j = new Janus();
j->Smile();
}
Although you call Smile
on a Janus
, the base class declarations are hidden.
The following doesn't:
struct FaceOfPast
{
virtual void Smile() {printf(":) ");}
};
struct FaceOfFuture
{
virtual void Smile() {printf(":) ");}
};
struct Janus : public FaceOfPast, public FaceOfFuture
{
};
int main()
{
Janus* j = new Janus();
j->Smile();
}
Because of the ambiguity.
According the C++ standard (10.3.2):
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf [...] overrides Base::vf.
There doesn't seem to be any special treatment for multiple inheritance, so it most probably apply here too: void Janus::Smile()
overrides both methods without any ambiguity, just because it has the exact same name and signature as both base class methods.
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