|
|
 |
|
|
|
|
void Speak()const { cout << Meow\n; }
void Purr()const { cout << rrrrrrrrrrrrrrrr\n; }
}; |
|
|
|
|
|
|
|
|
The problem is this: If you now call Purr() on your pointer, you will get a compile error. When you call Purr(), your compiler will reply: |
|
|
|
|
|
|
|
|
error C2039: Purr : is not a member of Mammal |
|
|
|
|
|
|
|
|
When your compiler tries to resolve Purr() in its Mammal virtual table, there will be no entry. At this point, you have a number of bad options. |
|
|
|
|
|
|
|
|
You can percolate this method up into the base class, but that is a very bad idea. Although it will work as an expedient, populating your base class with methods that are specific to derived classes is poor programming practice and a recipe for difficult-to-maintain code. |
|
|
|
|
|
|
|
|
In fact, this entire problem is a reflection of bad design. Generally, if you have a pointer to a base class that is assigned to a derived class object, it is because you intend to use that object polymorphically, and in this case, you ought not even try to access methods that are specific to the derived class. |
|
|
|
|
|
|
|
|
Let me be clear: The problem is not that you have such specific methods; it is that you are trying to get at them with the base class pointer. In an ideal world, when you have such a pointer you would not try to get at those methods. |
|
|
|
|
|
|
|
|
But this is not an ideal world, and at times, you find yourself with a collection of base objectsfor example, a zoo full of mammals. At one point or another, you might realize you have a Cat object and you want the darn thing to purr. In this case, there might be only one thing to do: cheat. |
|
|
|
|
|
|
|
|
This is the way you cheat: You cast your base class pointer to your derived type. You say to the compiler, Look, bub, I happen to know this is really a cat, so shaddup and do what I tell you. You have to sound like a thug when you say it, because you are acting like one; you are essentially extorting Cat behavior out of a Mammal pointer. |
|
|
|
|
|
|
|
|
To make this work, you'll use the new dynamic_cast operator. This operator ensures that when you cast, you cast safely. Further, it helps you quickly find those places in your code where you have used this feature, so that you can remove it as soon as you come to your senses. |
|
|
|
|
|
|
|
|
Here's how it works: If you have a pointer to a base class, such as Mammal, and you assign to it a pointer to a derived class, such as Cat, you can use the Mammal pointer polymorphically. Then, if you need to get at the Cat object to call, for example, the purr() method, you create a Cat pointer and use the dynamic_cast operator to make the conversion. |
|
|
|
|
|