Virtual functions

-- dispatching
  class A { 
\fbox{A}
public: virtual void operator()() { cout << "A"; } }; class B : public A {
\fbox{B}
public: virtual void operator()() { cout << "B"; } };
\nop{

Usage

  • A* a = new B(); (*a)();
} }{

Virtual functions

-- dispatching
  class A { 
\fbox{A}
public: virtual void operator()() { cout << "A"; } }; class B : public A {
\fbox{B}
public: virtual void operator()() { cout << "B"; } };
\nop{

Usage

  • A* a = new B(); (*a)();
} } } \c{ The class A defines a virtual member function (that results in printing A) which is redefined by a similar function in class B (which results in printing B). As an example of using the classes defined above look at the following program fragment.
  A* a = new B(); (*a)();
  
In case the function would not have been defined as virtual, the outcome of applying it to (a pointer to) a B object would have been A, instead of B. } \c{ Virtual functions that are redefined in derived classes may still access the original version defined in the base class, as illustated in slide 7-scoping. } \slide{7-scoping}{Virtual functions -- scoping}{

Scoping

-- explicit
  class B : public A {  
\fbox{B'}
public: virtual void operator()() { cout << "B"; A::operator()(); } };
}{

Scoping

-- explicit
  class B : public A {  
\fbox{B'}
public: virtual void operator()() { cout << "B"; A::operator()(); } };
} } \c{ Scoping may be used within a member function of the class as well as by a client (when invoking a member function) as illustrated below.
   A* a = new B(); a->A::operator()(); (*a)();
  
The outcome of this statement is ABA. Such a scoping mechanism is certainly not unique to C++, although the notation for it is. In Smalltalk, the expression super may be used to access methods defined in the ancestor class, and in Eiffel one must use a combination of redefining and renaming to achieve this. As a remark, occasionally I prefer the use of operator()() when any other method name would be arbitrary. The attractiveness of operator()() is that it is used as a function application operator, as in $(*a)(). } }