Глава 23. Динамическая идентификация типов_______________________643
Предположим, однако, что класс Apple является производным от более общего класса Fruit и программа получает указатель на Fruit. В этом случае нелегко определить, ссылается ли указатель на Apple, на KiwiFruit или на любой другой класс, производный от класса Fruit. Ситуация окажется еще хуже, если класс Fruit является производным от класса еще более высокого уровня GenericObject (это часто случается во многих библиотеках классов в стиле SmalTalk), и ваша программа получает указатель на GenericObject.
Может Оказаться, ЧТО работа Идет С Apple, ИЛИ KiwiFruit, ИЛИ С Boeing747.
Легко понять, насколько нежелательной может оказаться попытка очистить кожуру с объекта типа Boeing747 вместо Apple.
Приведение указателя GenericObject к типу Apple и вызов затем его метода peel () (очистить) может иметь катастрофический результат, если в действительности это указатель на объект Boeing747. Ясно, что классы C++ получили бы огромное преимущество, если бы имели четкий механизм определения типа объекта для указателя. К сожалению, выяснить тип вашего фрукта в C++ не столь просто, как в реальной жизни.
*
Есть такой метод
С самого начала развития C++ задачу идентификации типа программистам решать все-таки приходилось. Наиболее общим является определение виртуальной функции, обычно называемой isA(), на высшем уровне иерархии классов. Функция должна возвращать уникальное имя класса. По мере развития иерархии каждый новый производный класс должен заботиться о перефузке функции isA() так, чтобы она возвращала имя нового класса. Эта схема может быть реализована, например, способом, приведенном в листинге 23.1.
void MakeSalad. (GenericObject* pObject) (
switch (pObject->isA()){
case OBJ_APLE:
case OBJ_ORANGE:
case OBJ_BANANA:
pObject->Peel() ;
break:
case OBJ_LETTuCE:
pObject->Chop() ;
beak;
case OBJ_BOEING747:
cout « "Очень остроумно!\n"