Shell commands (cut & paste)
Sample shell output
Python configuration files (cut & paste)
C++ code (cut & paste)
// What is the method address in a derived class instence // for a virtual and a non-virtual method? #include <iostream> #include <stdio.h> using namespace std; //_____________________________________________________________________________ class A { public: void hello() { cout << "A: hello, world!" << endl; } void bye() { cout << "A: adios amigos!" << endl; } }; //_____________________________________________________________________________ class B : public A { public: /// This method shadows A::hello! void hello() { cout << "B: non-virtual hell, oh!" << endl; } /// No implementation of bye! }; //_____________________________________________________________________________ class C { public: virtual void hello() { cout << "C: hello!" << endl; } virtual void bye() { cout << "C: adios amigos!" << endl; } }; //_____________________________________________________________________________ class D : public C{ public: virtual void hello() { cout << "D: virtual hell, oh!" << endl; } virtual void bye() { cout << "D: virtual hell, oh!" << endl; } }; //_____________________________________________________________________________ int main(int argc, char** argv) { /// Print legend cout << "X * x = new X(); // X = A, C" << endl; cout << "X * xy = new Y(); // Y = B, D; Y derived from X" << endl; cout << "A::hello(), A::bye() are non-virtual" << endl; cout << "C::hello(), C::bye() are virtual" << endl; cout << "B::hello() re-implemented" << endl; cout << "B::bye() not implemented, only inherited from A" << endl; cout << endl; A * a = new A(); B * b = new B(); C * c = new C(); D * d = new D(); A * ab = new B(); C * cd = new D(); /// Sanity check cout << "x->hello();" << endl; cout << "x=a: "; a->hello(); cout << "x=b: "; b->hello(); cout << "x=c: "; c->hello(); cout << "x=d: "; d->hello(); cout << endl; cout << "x->bye();" << endl; cout << "x=a: "; a->bye(); cout << "x=b: "; b->bye(); cout << "x=c: "; c->bye(); cout << "x=d: "; d->bye(); cout << endl; /// Now the trickier part /// Here, ab behaves differently than cd! cout << "xy->hello();" << endl; cout << "xy=ab: "; ab->hello(); /// Calls the base class implementation. cout << "xy=cd: "; cd->hello(); /// Calls the derived class implementation. cout << endl; cout << "((Y*) xy)->hello();" << endl; cout << "xy=ab: "; ((B*) ab)->hello(); cout << "xy=cd: "; ((C*) cd)->hello(); cout << endl; /// Here, ab->bye() behaves differently than ab->hello()! cout << "xy->bye();" << endl; cout << "xy=ab: "; ab->bye(); cout << "xy=cd: "; cd->bye(); cout << endl; cout << "((Y*) xy)->bye();" << endl; cout << "xy=ab: "; ((B*) ab)->bye(); cout << "xy=cd: "; ((C*) cd)->bye(); cout << endl; delete a; delete b; delete c; delete d; delete ab; delete cd; return 0; }
D::hello()
provides a new implementation of C::hello()
. So may be the non-virtual methods, like B::hello()
provides a new implementation of A::hello()
.
A call to a non-virtual method in the derived class (b->hello(); b->bye();
) is resolved based on whether it is re-implemented in the derived class (like B::hello()
, then the re-implementation is used), or not (like B::bye()
, then the only available implementation in the base class is used: A::bye()
). This behavior changes if a pointer to the derived class is cast to the base class, like A* ab
below. Then the base class implementation is called A::hello()
is used.
Virtual methods behave differently. The derived class is called each time, e.g. both d->hello();
and cd->hello();
are resolved to D::hello()
.
X * x = new X(); // X = A, C X * xy = new Y(); // Y = B, D; Y derived from X A::hello(), A::bye() are non-virtual C::hello(), C::bye() are virtual B::hello() re-implemented B::bye() not implemented, only inherited from A x->hello(); x=a: A: hello, world! x=b: B: non-virtual hell, oh! x=c: C: hello! x=d: D: virtual hell, oh! x->bye(); x=a: A: adios amigos! x=b: A: adios amigos! x=c: C: adios amigos! x=d: D: virtual hell, oh! xy->hello(); xy=ab: A: hello, world! xy=cd: D: virtual hell, oh! ((Y*) xy)->hello(); xy=ab: B: non-virtual hell, oh! xy=cd: D: virtual hell, oh! xy->bye(); xy=ab: A: adios amigos! xy=cd: D: virtual hell, oh! ((Y*) xy)->bye(); xy=ab: A: adios amigos! xy=cd: D: virtual hell, oh!