Почему мой указатель базового класса не имеет доступа к функциям из производного класса?

0
class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
};

class Rectangle: public Polygon {
  public:
    int area()
      { return width*height; }
};

int main () {
  Rectangle rect;
  Polygon * ppoly1 = ▭
  ppoly1->set_values (4,5);
  cout << rect.area() << '\n';
  return 0;
}

В приведенном выше примере, на что указывает ppoly1, и как этот указатель не может получить доступ к функции класса прямоугольника?

ПОЧЕМУ ppoly1-> area() - ошибка

Благодарю!

  • 1
    Потому что вы можете получить доступ только к методам базового класса через указатель базового класса.
  • 1
    потому что у Polygon нет функции с именем area.
Теги:
inheritance

3 ответа

6

Выражение ppoly1->area() является ошибкой, потому что ppoly1 в Polygon который не имеет объявленного метода area. Когда C++ пытается оценить этот член, он, по сути, начинается с Polygon видит ни одной из названных area и, следовательно, выдает ошибку

Похоже, вы хотите присвоить типу Polygon понятие метода area без реализации (заставляя производные типы предоставлять один). Если это так, вы должны объявить не реализованный виртуальный метод в Polygon

class Polygon { 
  ...
  virtual ~Polygon() { } 
  virtual int area() = 0;
};
0

Базовые классы ничего не знают о своих производных классах. Когда базовый класс определяется, еще нет никакого производного класса.

Переменная ppoly1 относится к типу Polygon *. Класс Polygon не имеет области метода, поэтому компилятор выдает ошибку.

Если вы хотите использовать общий интерфейс для производных классов, вы должны объявить его в базовом классе. Например

class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    virtual int area() const = 0;
    virtual ~Polygon(){}
};

class Rectangle: public Polygon {
  public:
    int area() const
      { return width*height; }
};

int main () {
  Rectangle rect;
  Polygon * ppoly1 = &rect;
  ppoly1->set_values (4,5);
  cout << rect.area() << '\n';
  return 0;
}
0

ppoly1 - указатель многоугольника. Тот факт, что указатель указывает на объект Rectangle, не позволяет ему вызывать функции Rectangle; тип все еще Polygon*. Чтобы позволить ему вызывать функции Rectangle, вам нужно либо сделать его указателем Rectangle, либо реализовать виртуальный метод в вашем классе Polygon,

например

virtual int area() const;

Это означает, что если объект Polygon имеет area() вызывающую его, он будет искать наиболее производный экземпляр area(). На ppoly1 это будет Rectangle->area(). Вы можете сохранить код Rectangle таким же, как и раньше.

Википедия о виртуальных функциях: http://en.wikipedia.org/wiki/Virtual_function

Ещё вопросы

Сообщество Overcoder
Наверх
Меню