|
|
|
|
|
|
|
Analysis: On lines 3848, the user is asked to choose to add either a Cat or a Dog object to the array of Mammal pointers. Line 52 walks through the array and, on line 54, each object's virtual speak() method is called. These methods respond polymorphically: cats meow, and dogs say woof! |
|
|
|
|
|
|
|
|
On line 60, I want the Cat objects to purr, but I don't want to call that method on Dog objects. I used the dynamic_cast operator on line 57 to ensure that the object I am calling purr() on is a Cat. If it is, the pointer will not be null and will pass the test on line 59. |
|
|
|
|
|
|
|
|
Often, you will create a hierarchy of classes together. For example, you might create a Shape class, and derive from it Rectangle and Circle. From Rectangle, you might derive Square as a special case of Rectangle. |
|
|
|
|
|
|
|
|
Each of the derived classes will override the Draw() method, the GetArea() method, and so forth. Listing 18.3 illustrates a bare-bones implementation of the Shape class and its derived Circle and Rectangle classes. |
|
|
|
|
|
|
|
|
LISTING 18.3Shape CLASSES |
|
|
|
 |
|
|
|
|
1: //Listing 18.3. Shape classes.
2:
3: #include <iostream.h>
4:
5: class Shape
6: {
7: public:
8: Shape(){}
9: virtual ~Shape(){}
10: virtual long GetArea() { return -1; } // error
11: virtual long GetPerim() { return -1; }
12: virtual void Draw() {}
13: private:
14: };
15:
16: class Circle : public Shape
17: {
18: public:
19: Circle(int radius):itsRadius(radius){}
20: ~Circle(){}
21: long GetArea() { return 3 * itsRadius * itsRadius; }
22: long GetPerim() { return 9 * itsRadius; }
23: void Draw();
24: private: |
|
|
|
 |
|
|
|
|
continues |
|
|
|
|
|