|
|
|
|
|
|
|
FIGURE 17.3
The v-table of a Dog. |
|
|
|
|
|
|
|
|
You Can't Get There from Here |
|
|
|
|
|
|
|
|
If the Dog object had a method, WagTail(), that was not in the Mammal, you could not use the pointer to Mammal to access that method (unless you cast it to be a pointer to Dog). Because WagTail() is not a virtual function, and because it is not in a Mammal object, you can't get there without either a Dog object or a Dog pointer. |
|
|
|
|
|
|
|
|
Although you can transform the Mammal pointer into a Dog pointer, there are usually far better and safer ways to call the WagTail() method. C++ frowns on explicit casts because they are error-prone. This subject is addressed in depth when multiple-inheritance is covered in Hour 18, Advanced Polymorphism, and again when templates are covered in Hour 24, Exceptions and Error Handling. |
|
|
|
|
|
|
|
|
Note that the virtual function magic only operates on pointers and references. Passing an object by value will not enable the virtual member functions to be invoked. Listing 17.3 illustrates this problem. |
|
|
|
|
|
|
|
|
LISTING 17.3 DATA SLICING WHEN PASSING BY VALUE |
|
|
|
 |
|
|
|
|
1: //Listing 17.3 Data slicing with passing by value
2:
3: #include <iostream.h>
4:
5: class Mammal
6: {
7: public:
8: Mammal():itsAge(1) { }
9: ~Mammal() { }
10: virtual void Speak() const { cout << Mammal speak!\n; }
11: protected:
12: int itsAge;
13: }; |
|
|
|
 |
|
|
|
|
continues |
|
|
|
|
|