Язык программирования C++ от Страуструпа


..Контейнеры и удаление


Допустим, что у нас нет бесконечной памяти и сборщика мусора. На какие средства управления памятью может рассчитывать создатель контейнера, например, класса Vector? Для случая таких простых элементов, как int, очевидно, надо просто копировать их в контейнер. Столь же очевидно, что для других типов, таких, как абстрактный класс Shape, в контейнере следует хранить указатель. Создатель библиотеки должен предусмотреть оба варианта. Приведем набросок очевидного решения:

template<class T> Vector {

  T* p;

  int sz;

  public:

     Vector(int s) { p = new T[sz=s]; }

     // ...

};

Если пользователь не будет заносить в контейнер вместо указателей на объекты сами объекты типа Shape, то это решение подходит для обоих вариантов.

Vector<Shape*> vsp(200);           // нормально

Vector<Shape> vs(200);             // ошибка при трансляции

К счастью, транслятор отслеживает попытку создать массив объектов абстрактного базового класса Shape.

Однако, если используются указатели, создатель библиотеки и пользователь должны договориться, кто будет удалять хранимые в контейнере объекты. Рассмотрим пример:

void f()

  // противоречивое использование средств

  // управления памятью

{

  Vector<Shape*> v(10);

  Circle* cp = new Circle;

  v[0] = cp;

  v[1] = new Triangle;

  Square s;

  v[2] = &s;

  delete cp;                  // не удаляет объекты, на которые настроены

                               // указатели, находящиеся в контейнере

}

Если использовать реализацию класса Vector из $$1.4.3, объект Triangle в этом примере навсегда останется в подвешенном состоянии (на него нет указателей), если только нет сборщика мусора. Главное в управлении памятью это - это корректность. Рассмотрим такой пример:

void g()

// корректное использование средств управления памятью

{

  Vector<Shape*> v(10);

  Circle* cp = new Circle;

  v[0] = cp;

  v[1] = new Triangle;

  Square s;

  v[2] = &s;

  delete cp;

  delete v[1];

}

Рассмотрим теперь такой векторный класс, который следит за удалением занесенных в него указателей:




- Начало -  - Назад -  - Вперед -



Книжный магазин