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 haveA *a; C *c; a = new B; c = new D; c->func(*a);This produces:
A B C::func B::funcCostructors 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 beA B D::func B::func


No comments:
Post a Comment