Tuesday, October 20, 2009

22.10 ''Virtual'' methods



[ Team LiB ]










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()
{
cParentClass::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.



cChildClass::~cChildClass()
{
//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. */
}





    [ Team LiB ]



    No comments:

    Post a Comment