Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ
Шрифт:
Это странное поведение при копировании
Альтернатива auto_ptr – это интеллектуальные указатели с подсчетом ссылок (reference-counting smart pointer – RCSP). RCSP – это интеллектуальный указатель, который отслеживает, сколько объектов указывают на определенный ресурс, и автоматически удаляет ресурс, когда никто на него не ссылается. Следовательно, RCSP ведет себя подобно сборщику мусора. Но, в отличие от сборщика мусора, RCSP не может разорвать циклические ссылки (когда два неиспользуемых объекта указывают друг на друга).
Класс tr1::shared_prt из библиотеки TR1 (см. правило 54) – это типичный пример RCSP, поэтому вы можете написать:
Этот код выглядит почти так же, как и использующий auto_ptr, но shared_ptr при копировании ведет себя гораздо более естественно:
Поскольку копирование объектов tr1::shared_ptr работает «как ожидается», то они могут быть использованы в качестве элементов STL-контейнеров, а также в других случаях, когда непривычное поведение auto_ptr нежелательно.
Однако не заблуждайтесь. Это правило посвящено не auto_ptr и tr1::shared_ptr, или
И auto_ptr, и tr1::shared_ptr в своих деструкторах используют оператор delete, а не delete[]. (Разница между ними описана в правиле 16.) Это значит, что нельзя применять auto_ptr и tr1::shared_ptr к динамически выделенным массивам, хотя, как это ни прискорбно, следующий код скомпилируется:
Вас может удивить, что не предусмотрено ничего подобного auto_ptr или tr1::shared_ptr для работы с динамически выделенными массивами – ни в C++, ни даже в TR1. Это объясняется тем, что такие массивы почти всегда можно заменить векторами или строками (vector и string). Если вы все-таки считаете, что было бы неплохо иметь auto_ptr и tr1::shared_ptr для массивов, обратите внимание на библиотеку Boost (см. правило 55). Там вы найдете классы boost::scoped_array и boost::shared_array, которые предоставляют нужное вам поведение.
Излагаемые здесь правила по использованию объектов для управления ресурсами предполагают, что если вы освобождаете ресурсы вручную (например, применяя delete помимо того, который содержится в деструкторе управляющего ресурсами класса), то поступаете неправильно. Готовые классы для управления ресурсами – вроде auto_ptr и tr1::shared_ptr – часто облегчают выполнение советов из настоящего правила, но иногда приходится иметь дело с ресурсами, для которых поведение этих классов неадекватно. В таких случаях вам придется разработать собственные классы управления ресурсами. Это не так уж трудно сделать, но нужно принять во внимание некоторые соображения (см. правила 14 и 15).
И в качестве завершающего комментария я должен сказать, что возврат из функции createInvestment обычного указателя – это путь к утечкам ресурсов, потому что после обращения к ней очень просто забыть вызвать delete для этого указателя. (Даже если используются auto_ptr или tr1::shared_ptr для выполнения delete, нужно не забыть «обернуть» возвращенное значение интеллектуальным указателем.) Чтобы решить эту проблему, нам придется изменить интерфейс createInvestment, и это станет темой правила 18.
• Чтобы предотвратить утечку ресурсов, используйте объекты RAII, которые захватывают ресурсы в своих конструкторах и освобождают в деструкторах.
• Два часто используемых класса RAII – это tr1::shared_ptr и auto_ptr. Обычно лучше остановить выбор на классе tr1::shared_ptr, потому что его поведение при копировании соответствует интуитивным ожиданиям. Что касается auto_ptr, то после копирования он уже не указывает ни на какой объект.
Сердце Дракона. Том 20. Часть 1
20. Сердце дракона
Фантастика:
фэнтези
боевая фантастика
городское фэнтези
рейтинг книги
Холодный ветер перемен
7. Девяностые
Фантастика:
попаданцы
альтернативная история
рейтинг книги
Последнее желание
1. Ведьмак
Фантастика:
фэнтези
рейтинг книги
Отмороженный 7.0
7. Отмороженный
Фантастика:
рпг
аниме
рейтинг книги
Наследник
1. Рюрикова кровь
Фантастика:
научная фантастика
попаданцы
альтернативная история
рейтинг книги
