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) член класса, указывающий на размещенные данные):
<< назад вперед >>