dominance
there is a thing called name dominance in C++. consider this:
class A
{
public:
int f() { printf("\nA::f()"); return 1; }
};
class B : virtual public A
{
public:
void f() { printf("\nB::f()"); } // hides the int A::f()
};
class C : virtual public A
{
};
class D : public B, public C
{
};
the hierarchy is this:
A
B C
D
and D has only one copy of A in memory (beacuse B and C inherits virtual from A)
now:
D d;
d.f();
f() is not ambigous because void B::f() hides int A::f().
d.f() will get B:f() called because D derives from B which hides the A::f().
Note that this is not ambigous beacause the A is virtual inherited in B and C and this makes that the d object to contain only one instance of A within it. if, for example, B or C will not have virtual inherited from A (either one of them or both) this will mean that d will have 2 A objects within it.
now, consider this case:
C *d = new D;
d->f();
d->f() will get A:f() called.
Why is that stays in the mechanism of calling a function.
in the first case, when d is a D object:
D d;
when you call
d.f();
the function which is get called is determined at compile time; the function called is the D::f()
in the 2nd case, when
C *d = new D;
when you call
d->f();
the object d is really a D object but since the function called is not virtual (not taken from the vtable) the function called is from C object scope, which is A::f(), beacuse C inherits A::f().
hence, the rule is this:
if the function called is not virtual, the function called is the one from the type of the object type.
class A
{
public:
int f() { printf("\nA::f()"); return 1; }
};
class B : virtual public A
{
public:
void f() { printf("\nB::f()"); } // hides the int A::f()
};
class C : virtual public A
{
};
class D : public B, public C
{
};
the hierarchy is this:
A
B C
D
and D has only one copy of A in memory (beacuse B and C inherits virtual from A)
now:
D d;
d.f();
f() is not ambigous because void B::f() hides int A::f().
d.f() will get B:f() called because D derives from B which hides the A::f().
Note that this is not ambigous beacause the A is virtual inherited in B and C and this makes that the d object to contain only one instance of A within it. if, for example, B or C will not have virtual inherited from A (either one of them or both) this will mean that d will have 2 A objects within it.
now, consider this case:
C *d = new D;
d->f();
d->f() will get A:f() called.
Why is that stays in the mechanism of calling a function.
in the first case, when d is a D object:
D d;
when you call
d.f();
the function which is get called is determined at compile time; the function called is the D::f()
in the 2nd case, when
C *d = new D;
when you call
d->f();
the object d is really a D object but since the function called is not virtual (not taken from the vtable) the function called is from C object scope, which is A::f(), beacuse C inherits A::f().
hence, the rule is this:
if the function called is not virtual, the function called is the one from the type of the object type.
Comments
Post a Comment
Say something nice please.
Thank you.