Большинство интеллектуальных указателей владеют объектом, на который они указывают - они отвечают за уничтожение этого объекта, когда придет время. Однако разные интеллектуальные указатели имеют разную семантику владения. То есть они сообщают пользователю этого интеллектуального указателя, как право собственности может или не может быть передано, как оно распределяется между объектами, когда объект должен быть удален и т. Д. Использование определенного умного указателя описывает ваше намерение в отношении владения этим объектом. Право собственности может быть передано другим функциям или объектам.
boost::scoped_ptr
имеет очень строгую семантику владения. Он вообще не допускает передачи права собственности. Это достигается тем, что его нельзя копировать (поэтому вы не можете передать его другой функции по значению).
Другой пример: std::unique_ptr
тоже довольно строгий. Его особая способность заключается в том, что его можно перемещать. Передача std::unique_ptr
функции в качестве rvalue позволит этой функции украсть право собственности на объект. Оригинальный std::unique_ptr
немедленно теряет это право собственности. Это гарантирует, что право собственности всегда принадлежит только одному std::unique_ptr
.
Эквивалент boost::scoped_ptr
в C ++ 11 - const std::unique_ptr
. Это связано с тем, что его установка const
предотвращает любое перемещение и, следовательно, не может быть передана собственность.
Простой способ увидеть, насколько важна семантика владения, - это на примере. Допустим, вы используете библиотеку злого разработчика, и в ней есть функция, о реализации которой вы не знаете, например:
cat* foo();
Вы знаете, что эта функция возвращает указатель на cat
. Однако это необработанный указатель. Вы понятия не имеете, нужно ли вам когда-нибудь уничтожать кошку (с помощью delete
) или библиотека сделает это за вас. Вы даже не знаете, действительно ли объект был размещен динамически. Вы понятия не имеете, хранит ли библиотека файл cat
. Раньше, если у вас была такая функция, вам нужно было поискать в документации, что делать. Однако теперь, когда у нас есть интеллектуальные указатели в дополнение к необработанным указателям, необработанные указатели имеют свою собственную семантику владения - наиболее расслабленную из всех. В нем говорится: «Вам лучше поверить мне, что я сохраню это cat
в силе, пока вы его передадите, но я буду управлять этим. Не храните его слишком долго».
Однако теперь мудрый и добрый разработчик библиотеки напишет эту функцию так:
std::unique_ptr<cat> foo();
Так как это помогает? Что ж, std::unique_ptr
говорит вам о многом. Он сообщает вам, что функция передает вам право владения объектом cat
. cat
теперь ваша исключительная ответственность. Это также очень полезно для того, чтобы дать вам умный указатель, потому что вам не нужно думать о delete
его установке. Вы можете просто использовать указатель, и когда он выйдет за пределы области видимости, объект будет уничтожен. Или, если хотите, вы можете передать право собственности другой функции.
Это не означает, что только один указатель когда-либо будет владеть cat
. Вам, как счастливому новому владельцу, решать, что будет дальше. Совершенно разумно решить, что вы хотите начать совместное владение своим cat
:
std::unique_ptr<cat> up = foo();
std::shared_ptr<cat> sp(up.release());
Мудрый и добрый foo
разработчик библиотеки только рассказал вам, каковы ее намерения. Она дала тебе cat
, и теперь ты владелец. Теперь вы можете предоставить свою собственную семантику владения.
Таким образом, boost::scoped_ptr
немного похож на жадного cat
собирателя, который никогда ни с кем не поделится cat
, никогда никому не отдаст кошку и будет хранить ее до дня своей смерти.
person
Joseph Mansfield
schedule
02.02.2013