воскресенье, 26 февраля 2012 г.
четверг, 23 февраля 2012 г.
вторник, 21 февраля 2012 г.
Неглупые указатели (smart_pointers)
Студент увидел как-то на рынке, что какой-то мужик
продает мозги разных специалистов. Заинтересовался,
подходит, спрашивает что почем. Ему объясняют:
«Это мозги математика, они по сто рублей за килограмм,
это – мозги физика, они – по двести за кило, а вот эти
– мозги философа, они самые дорогие, по две тысячи».
Студент проникся уважением, спрашивает:
«Что, философские мозги и правда такие хорошие?»
«Да нет, дело не в этом, просто представь, это же
сколько философов отловить надо, чтобы набрать
целый килограмм мозгов!»
– мозги философа, они самые дорогие, по две тысячи».
Студент проникся уважением, спрашивает:
«Что, философские мозги и правда такие хорошие?»
«Да нет, дело не в этом, просто представь, это же
сколько философов отловить надо, чтобы набрать
целый килограмм мозгов!»
Прочитав Скотта Майерса, я стала противником auto_ptr. Auto_ptr - это зло-зло! Я об этом сказала своему начальнику. Он же сделал круглые глаза и выразил удивление, чем меня сильно озадачил. Я опять повторила: "Зло-Зло!". А он: "Почему?". Когда я объяснила, почему зло, он сделал простейший вывод: "Просто не надо их использовать в контейнерах." Действительно, подумала я... :)
И так небольшой обзор умных указателей:
STL:
- auto_ptr - только не для использования в контейнерах!! (См. Скотт Майерс, "Effective STL", совет №8)
- weak_ptr - (доступен только в ISO/IEC 14882:2011, или при указании опции компиляции -std=c++0x)
- shared_ptr - (доступен только в ISO/IEC 14882:2011, или при указании опции компиляции -std=c++0x)
И вообще, в файлы с новым стандартом лучше не заглядывать - незаметно сносит крышу. То есть вроде бы всё на месте, а холодком веет. Необычные конструкции вроде таких, пугают: shared_ptr(shared_ptr&& __r), но об этом можно почитать здесь.
Boost:
- scoped_ptr - самый простой умный указатель. Как написано в комментариях - simple solution for simple needs. Умеет возвращать память при выходе из области видимости (в деструкторе). Умеет делать get(), reset(), swap();
- intrusive_ptr - умный указатель со встроенным счетчиком ссылок. Может быть создан из произвольного raw-указателя (сырого указателя) типа T*. Блок памяти для intrusive_ptr такой же, как и для соответствующего raw-указателя. Умеет делать get(), reset(), swap(). Но для него придется определить функции подсчета ссылок и освобождения памяти. В конструкторе intrusive_ptr( T * p, bool add_ref = true ) вторым параметром (как это ясно из названия) можно повлиять на увеличение счетчика в первый раз. Его удобно использовать при разработке, где требуется самому определять не только, как освободить память, но и как работает счетчик ссылок. Главное правильно, если не ясно какой из двух использовать: его или shared_ptr, попробуйте использовать сначала shared_ptr;
- weak_ptr - слабенький указатель :). Используется совместно с shared_ptr. Хранит ссылку на объект, которым уже владеет shared_ptr. Для доступа к хранимому объекту нужно перейти к shared_ptr, используя соответствующий конструктор: template<class Y> explicit shared_ptr(weak_ptr<Y> const & r). Есть внутренние переменные: указатель на данные, счетчик ссылок (boost::detail::weak_count). Умеет делать lock() - защита от удаления объекта и сказать, что объект уже никем не используется с помощью функции expired();
- shared_ptr - умный указатель посложнее. Есть внутренние переменные - указатель на данные, счетчик ссылок (boost::detail::shared_count). Его использование гарантирует, что объект будет удален, когда последний shared_ptr, указывающий на него, уничтожится или сбросится (reset()).
Подписаться на:
Сообщения (Atom)