Подтвердить что ты не робот

Полиморфизм С++: проверка типа данных подкласса

Возможный дубликат:
Поиск типа объекта в С++

Здравствуйте,
Мне жаль, если это дубликат, но я не смог найти ответ на мой вопрос здесь. Предположим, что мы имеем следующую структуру классов в С++:

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?

4b9b3361

Ответ 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 и посмотреть, дает ли он правильный результат или нет.