Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

// очень упрощенный вектор, содержащий числа типа double

class vector {

int sz; // размер

double* elem; // указатель на элементы

public:

vector(int s) // конструктор

:sz(s), elem(new double[s]) // выделяет память

{

for (int i=0; i<s; ++i) elem[i]=0; // инициализируем

// элементы

}

~vector // деструктор

{ delete[] elem; } // освобождаем память

// ...

};

Итак, теперь можно написать следующий код:

void f3(int n)

{

double* p = new double[n]; // выделяем память для n

// чисел типа double

vector v(n); // определяем вектор (выделяем память

// для других n чисел типа double)

// ...используем p и v...

delete[ ] p; // освобождаем память, занятую массивом

// чисел типа double

} // класс vector автоматически освободит

// память, занятую объектом v

Оказывается, оператор

delete[]
такой скучный и подвержен ошибкам! Имея класс
vector
, нет необходимости ни выделять память с помощью оператора
new
, ни освобождать ее с помощью оператора
delete[]
при выходе из функции. Все это намного лучше сделает класс
vector
. В частности, класс
vector
никогда не забудет вызвать деструктор, чтобы освободить память, занятую его элементами.

Здесь мы не собираемся глубоко вдаваться в детали использования деструкторов. Отметим лишь, что они играют очень важную роль при работе с ресурсами, которые сначала резервируются, а потом возвращаются обратно файлами, потоками, блокировками и т.д. Помните, как очищались потоки
iostream
? Они очищали буферы, закрывали файлы, освобождали память и т.д. Все это делали их деструкторы. Каждый класс, “владеющий” какими-то ресурсами, должен иметь деструктор.

17.5.1. Обобщенные указатели

Если член класса имеет деструктор, то этот деструктор будет вызываться при уничтожении объекта, содержащего этот член. Рассмотрим пример.

struct Customer {

string name;

vector<string> addresses;

// ...

};

void some_fct

{

Customer fred;

// инициализация объекта fred

// использование объекта fred

}

Когда мы выйдем из функции

some_fct
и объект
fred
покинет свою область видимости, он будет уничтожен; иначе говоря, будут вызваны деструкторы для строки name и вектора
addresses
. Это совершенно необходимо, поскольку иначе могут возникнуть проблемы. Иногда это выражают таким образом: компилятор сгенерировал деструктор для класса
Customer
, который вызывает деструкторы членов. Такая генерация выполняется компилятором часто и позволяет гарантированно вызывать деструкторы членов класса.

Деструкторы для членов — и для базовых классов — неявно вызываются из деструктора производного класса (либо определенного пользователем, либо сгенерированного). По существу, все правила сводятся к одному: деструкторы вызываются тогда, когда объект уничтожается (при выходе из области видимости, при выполнении оператора

delete
и т.д.).

17.5.2. Деструкторы и свободная память

Деструкторы концептуально просты, но в то же время они образуют основу для большинства наиболее эффективных методов программирования на языке С++. Основная идея заключается в следующем.

• Если функции в качестве ресурса требуется какой-то объект, она обращается к конструктору.

• На протяжении своего срока существования объект может освобождать ресурсы и запрашивать новые.

• В конце существования объекта деструктор освобождает все ресурсы, которыми владел объект.

Типичным примером является пара “конструктор–деструктор” в классе

vector
, которая управляет свободной памятью. Мы еще вернемся к этой теме в разделе 19.5. А пока рассмотрим важное сочетание механизма управления свободной памятью и иерархии классов.

  • Читать дальше
  • 1
  • ...
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: