|
|
 |
|
|
|
|
57: break;
58: case 4: ptr = new Pig;
59: break;
60: default: ptr = new Mammal;
61: break;
62: }
63: theArray[i] = ptr;
64: }
65: for (i=0;i<5;i++)
66: theArray[i]->Speak();
67: return 0;
68: } |
|
|
|
|
|
|
|
|
(1)dog (2)cat (3)horse (4)pig: 1
(1)dog (2)cat (3)horse (4)pig: 2
(1)dog (2)cat (3)horse (4)pig: 3
(1)dog (2)cat (3)horse (4)pig: 4
(1)dog (2)cat (3)horse (4)pig: 5
Woof!
Meow!
Winnie!
Oink!
ammal Speak! |
|
|
|
|
|
|
|
|
Analysis: This stripped-down program, which provides only the barest functionality to each class, illustrates virtual member functions in their purest form. Four classes are declared, Dog, Cat, Horse, and Pig, all derived from Mammal. |
|
|
|
|
|
|
|
|
On line 10, Mammal's Speak() function is declared to be virtual. On lines 18, 25, 32, and 38, the four derived classes override the implementation of Speak(). |
|
|
|
|
|
|
|
|
The user is prompted to pick which objects to create, and the pointers are added to the array in lines 4663. |
|
|
|
|
|
|
|
|
Note that at compile time it is impossible to know which objects will be created, and therefore, which Speak() methods will be invoked. The pointer ptr is bound to its object at runtime. This is called dynamic binding, or runtime binding, as opposed to static binding, or compile-time binding. |
|
|
|
|
|
|
|
|
|
How Virtual Member Functions Work. |
|
|
|
|
|
|
|
|
When a derived object, such as a Dog object, is created, first the constructor for the base class is called and then the constructor for the derived class is called. Figure 17.1 shows what the Dog object looks like after it is created. Note that the Mammal part of the object is contiguous in memory with the Dog part. |
|
|
|
|
|