Let's assume you have such classes:
class A
{
public:
A() {cout << "A" << endl;}
virtual void func() {cout << "A::func" << endl;}
};
class B : public A
{
public:
B() {cout << "B" << endl;}
virtual void func() {cout << "B::func" << endl;}
};
class C
{
public:
virtual void func(A &a) {cout << "C::func" << endl; a.func();}
};
class D : public C
{
public:
virtual void func(B &b) {cout << "D::func" << endl; b.func();}
};
And when you have
A *a;
C *c;
a = new B;
c = new D;
c->func(*a);
This produces:
A
B
C::func
B::func
Costructors from A and B invoked, and ... method C::func invoked even
c is an instance of D.
Compiler doesn't know anything about method
func from D and it's not overwritten in virtual table because it has different semantics, so C::func was executed. To let compiler correctly execute D::func the prototype of D::func should take a reference to A as an argument.
Class D can be defined like this:
class D : public C
{
public:
virtual void func(A &a) {cout << "D::func" << endl; a.func();}
};
In this case the output will be
A
B
D::func
B::func
No comments:
Post a Comment