#include "iostream.h"

class TFigure
{
    public:
    // Добавляем еще один параметр в конструктор базового класса (количество точек,
    // необходимое для представления дочернего объекта), и всю работу по инициализации
    // массива точек (естественно, и удалению тоже) перекладываем на базовый класс
    TFigure(int numPoints, const char *s = ""):
            name(s), ptsAmount(numPoints)
    {
        // Это теперь делается только здесь, и нигде больше
        pts = new TPoint[ptsAmount];
        cout << name << " created ..." << endl;

        for(int i = 0; i < ptsAmount; i++) {
            // И заполнение координат точек тоже здесь же
            // Это - более универсальный метод, если тебе захочется поменять фомрмат ввода или
            // добавить какой-нибудь диалог, что проще, сделать это ТОЛЬКО здесь или бегать по
            // всем классам и искать, где же еще производятся эти действия?
            TPoint p;
            cout << "Enter coordinates of apex" << i+1 << ":";
            cin >> p.x >> p.y;
            pts[i] = p;

        }
    }

    // А вот теперь объявляем деструктор, и в нем - удаление массива...
    virtual ~TFigure()
    {
      delete [] pts;
    }

    // Поскольку move_it делает одни и те же действия для всех (по крайней мере,
    // уже введенных в иерархию) классов, есть смысл перенести ее тоже в базовый класс,
    // поскольку мы уже знаем здесь и количество точек, с которыми производится работа...

    // Тогда нет даже необходимости делать функцию виртуальной, просто из потомка будет 
    // вызываться метод базового класса
    void move_it(int step_x, int step_y) {
        for(int i = 0; i < ptsAmount; i++)
        {
            pts[i].x += step_x;
            pts[i].y += step_y;
        }
    }

    // Аналогично и для show_position ...
    void show_position() {
      for(int i = 0;i < ptsAmount; i++)
        cout << " (" << pts[i].x << ";" << pts[i].y << ") ";
    }

    struct TPoint
    {
        TPoint(int px = 0, int py = 0): x(px), y(py)
        {
        }
        int x, y;
    };

    virtual double getS() const = 0;

  private:
    const char *name;

  // В "защищенном" разделе храним ниформацию, к которой не должно быть доступа
  // ниоткуда, кроме как из классов - потомков
  protected:
    int ptsAmount;
    TPoint *pts;
};

class TTriangle: public TFigure
{
  public:
    // По умолчанию задаем число точек треугольника = 3 (хотя можно было бы вообще сделать так:
    //  TTriangle(): TFigure(3, "triangle") {}
    // ,чтобы не позволить создать, например, треугольник - "мутант" с шестью углами...)
    TTriangle(int numPoints = 3) : TFigure(numPoints, "triangle") {
    }

    // Эту функцию проверь, по-моему она у тебя возвращает неверный результат !!!
    double getS() const
    {
      return 0.5*(pts[0].y*pts[1].x-pts[1].y*pts[0].x+
                  pts[1].y*pts[2].x-pts[2].y*pts[1].x-
                  pts[0].y*pts[2].x+pts[0].y*pts[0].x);
    }

};

class TPentagon: public TFigure
{
    public:
      // Такжк, как и в TTriangle, можно сделать по-другому...
      TPentagon(int numPoints = 5): TFigure(numPoints, "pentagon") {
    }

    double getS() const
    {
      return 12.0;
    }

};

char Compare(const TFigure &T1, const TFigure &T2)
{
    return (T1.getS() < T2.getS()) ? '<' : '>';
}


int main() {

  TTriangle T1;
  T1.show_position(); // Ты все время забываешь () при вызове метода/функции, а в С это необходимо
  cout << T1.getS() << endl; // площадь
  T1.move_it(2,2); // перемещаем
  T1.show_position(); // проверяем новые координаты
  cout << T1.getS() << endl; // проверяем площадь
  // (у меня первое значение площади не совпало со вторым)

  TPentagon T2;
  T2.show_position(); // позиция
  cout << T2.getS() << endl; // площадь
  T2.move_it(2,2); // перемещаем
  T2.show_position(); // проверяем новые координаты
  cout << T2.getS() << endl; // проверяем площадь

  cout << Compare(T1, T2) << endl;
  cout << Compare(T2, T1) << endl; // результаты и есть разные...

  return 0;

}