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::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 be
A B D::func B::func
No comments:
Post a Comment