|
|
 |
|
|
|
|
24: void Move()const { cout << Dog moves 5 steps\n; }
25: };
26:
27: int main()
28: {
29:
30: Mammal *pDog = new Dog;
31: pDog->Move();
32: pDog->Speak();
33:
34: return 0;
35: } |
|
|
|
|
|
|
|
|
Mammal constructor
Dog Constructor
Mammal move one step
Woof! |
|
|
|
|
|
|
|
|
Analysis: On line 11, Mammal is provided a virtual methodspeak(). The designer of this class thereby signals that she expects this class to eventually be another class's base type. The derived class will probably want to override this function. |
|
|
|
|
|
|
|
|
On line 30, a pointer to Mammal is created, pDog, but it is assigned the address of a new Dog object. Because a Dog is a Mammal, this is a legal assignment. The pointer is then used to call the Move() function. Because the compiler knows pDog only to be a Mammal, it looks to the Mammal object to find the Move() method. |
|
|
|
|
|
|
|
|
On line 32, the pointer then calls the Speak() method. Because Speak() is virtual, the Speak() method overridden in Dog is invoked. |
|
|
|
|
|
|
|
|
This is almost magicalas far as the calling function knew, it had a Mammal pointer, but here a method on Dog was called. In fact, if you have an array of pointers to Mammal, each of which points to a subclass of Mammal, you can call each in turn and the correct function is called. Listing 17.2 illustrates this idea. |
|
|
|
|
|
|
|
|
LISTING 17.2 MULTIPLE VIRTUAL MEMBER FUNCTIONS CALLED IN TURN |
|
|
|
 |
|
|
|
|
1: //Listing 17.2 Multiple virtual member functions called in turn
2:
3: #include <iostream.h>
4:
5: class Mammal
6: {
7: public:
8: Mammal():itsAge(1) { } |
|
|
|
 |
|
|
|
|
continues |
|
|
|
|
|