Полиморфизм С++: проверка типа данных подкласса
Возможный дубликат:
Поиск типа объекта в С++
Здравствуйте,
Мне жаль, если это дубликат, но я не смог найти ответ на мой вопрос здесь.
Предположим, что мы имеем следующую структуру классов в С++:
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
};
class CRectangle: public CPolygon {
public:
int area ()
{ return (width * height); }
};
Теперь у меня есть указатель на объект CPolygon. Как проверить, действительно ли это указатель на объект класса CRectangle?
Ответы
Ответ 1
Вы можете сделать это, установив, что dynamic_cast<CRectangle*>(ptr)
возвращает ненулевое значение, где ptr
- указатель на CPolygon
. Однако для этого требуется, чтобы базовый класс (CPolygon
) имел по крайней мере одну виртуальную функцию-член, которая вам, вероятно, нужна в любом случае (по крайней мере, виртуальный деструктор).
Ответ 2
В идеале вы этого не делаете. Вы используете полиморфизм, чтобы делать правильные вещи:
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area() const = 0;
};
class CRectangle: public CPolygon {
public:
int area () const
{ return (width * height); }
};
Вызовите area()
на указателе CPolygon, и вы получите область для CRectangle, если это так. Все, происходящее от CPolygon, должно будет реализовать area()
или вы не сможете его создать.
Ответ 3
Вы можете динамически это сделать:
CRect* pRect = dynamic_cast<CRect*>(MyPolygonPointer);
if(pRect != 0)
{
//...it is a CRect
}
Но, естественно, унижение является плохой практикой и должно использоваться с осторожностью. В хорошем дизайне вас не волнует фактический динамический тип указателя.
Ответ 4
Вы можете выполнить dynamic_cast для CRectangle и посмотреть, дает ли он правильный результат или нет.