22.10 ''Virtual'' methods

The keyword virtual in front of a parent class method tells the C++ compiler that the class has a child class which has a method which has the same name but which acts differently in the child class. If (a) a method is declared as virtual, and (b) the object which calls the method is referred to via a pointer, then (c) the compiled program will, even while it is running, be able to decide which implementation of the virtual method to use. It is worth stressing that this 'runtime binding' only works if you the programmer fulfill both conditions: (a) you use virtual in your method declaration, and (b) you use a pointer to your object.

Except in the case of a destructor, corresponding virtual functions have the same name. You don't put the word virtual in front of the actual function implementation code in the *.cpp. You can put virtual in front of the child class function declaration in the child class's header file or not, as you like. In other words, to start with, you really only need to put virtual in one place: in front of the parent class's declaration of the function.

But, in order to make our code more readable, when we derive off child classes from a parent class with a virtual function, we usually do put virtual in front of the child method declaration as well as in the parent method declaration. The child does need to have a declaration for the method in order to override it in any case.

One slightly weird thing is that a parent class destructor like ~cProgrammer() needs to be declared virtual even though a child class destructor like ~cTeacherProgrammer() seems to have a different name. But you don't in fact call the destructor by name. In a program where we have a cProgrammer *_ptextbookauthor, we might be calling either the cProgrammer or the cTeacher destructor with a line like delete _ptextbookauthor;. The thing is, it's possible that _ptextbookauthor got initialized as new cTeacher, so we just don't know.

The delete operator calls the destructor without referring to the destructor method by name. So the compiled code needs to actually look at the type of the _textbookauthor pointer to find out whether it's really a cProgrammer * or a cTeacherProgrammer*, so it knows which destructor to use. And unless you fulfilled the 'virtual condition' by making the destructor virtual, then the code won't know to do runtime binding and choose between using the parent or the child method as appropriate. The destructors are different here because the cTeacherProgrammer has more stuff to destroy, in particular, the cGollywog *_pimaginaryfriend.

Slogan for a class: If your child is richer than you, you need a virtual destructor.

One final point should be mentioned here. Ordinarily, when you have a method virtual void somemethod() in a base class called, say, cParentClass, then when you override the method in a child class called, say, cChildClass, the child class somemethod() will call the parent class method if we explicitly ask it to with code like this.

void cChildClass::somemethod() 
    //Your extra childclass code goes here.... 

But in the case of a virtual destructor, the parent class's destructor method will be automatically called when the object is deleted. This is in accord with the standard C++ execution order of constructors and destructors mentioned in the last subsection.

    //Your extra child class destructor code goes here... 
    /* The cParentClass::~cParentClass destructor will be 
        automatically called 
        here at the end of the ~cChildClass destructor call. */ 

    Part I: Software Engineering and Computer Games
    Part II: Software Engineering and Computer Games Reference