Friday, February 03, 2006

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.

No comments: