1.14. Класс auto_ptr

После того как размещена динамическая память, нужно внимательно следить за тем, чтобы она была правильно освобождена. Обычно программисты на С используют для этого malloc и free, а программисты на C++ используют так­же new и delete. Первое, о чем необходимо помнить, что после

int  *p  = new int; int  *q = new int[n];

в дальнейшем требуется выполнить следующие операторы:

delete р; delete []   q;

Пара квадратных скобок [] должна использоваться для q, но не для р; не­соблюдение этого правила - довольно частая причина ошибок. Другая сложность заключается в необходимости отслеживать копии указателей. Например, если мы напишем

int  *a = new int[n],   *b; b = а;

а и b будут указывать на один и тот же блок памяти. Освобождение этого блока должно быть проведено только один раз, поэтому позже мы должны выполнить либо

delete []   a; либо

delete[]   b;

но не оба эти выражения.

В STL определен специальный класс autojptr, который делает более бе­зопасным использование оператора new в сложных случаях. Функция-член get возвращает указатель на сами данные. Если мы присвоим значе­ние autojptr а переменной Ь, указателю a.get() автоматически будет присвоено значение NULL, например:

// auto_ptr.срр:   Данным соответствует // только один указатель, ♦include <iostream> ♦include <memory> using namespace  std;

int main()

{ auto_ptr<int> a(new int), b;

*a.get() = 123;

cout « "*a.get() = " « *a.get() « endl;

b = a;

cout « "The assignment b = a has been executed.\n";

if (a.getf) == NULL)

cout  <<   "As  a result,   a.getf)   is NULL.\n";

cout «  "*b.get()   =  "  « *b.get()   « endl;

return 0; }

Вывод этой программы следующий:

*a.get()   =  123

The assignment b = a has been executed. As  a result,   a.getf)   is NULL. *b.get()   =  123

Поскольку выражение a.get() является обычным указателем, значение, на которое оно указывает, обозначается как *a.get(). Преимущество исполь­зования класса auto_ptr заключается в том, что память освобождается ав­томатически, когда уничтожается объект, принадлежащий этому классу, и это происходит только один раз: в нашем примере переменные а и b не содержат одновременно указатели на одну и ту же область памяти. Для прояснения механизма действия класса auto_ptr посмотрим на его де­структор (в этом коде the_p - скрытый (private) член класса, указыва­ющий на размещенные данные):


<< назад вперед >>