Передача объекта в С++
Каков наилучший способ указать, что объект хочет взять на себя ответственность за другой объект? До сих пор я использовал std::auto_ptr
в открытом интерфейсе, поэтому клиент знает, что интерфейс хочет взять на себя ответственность за переданный объект.
Однако последний GCC говорит мне, что auto_ptr
устарел, поэтому мне интересно, что рекомендуется? boost::interprocess::unique_pointer
выглядит хорошим кандидатом, но действительно ли это лучшее решение?
Ответы
Ответ 1
boost::interprocess
- это библиотека для межпроцессного общения, поэтому я не буду использовать ее для разных целей.
Как обсуждалось на этом форуме:
http://objectmix.com/c/113487-std-auto_ptr-deprecated.html
std::auto_ptr
будет объявлен устаревшим в следующей версии стандарта, где будет рекомендовано использовать std::unique_ptr
, для чего требуются ссылки на rvalue и перемещать семантику (что довольно сложная функция).
Пока новый стандарт не будет выпущен, я просто попытался бы отключить предупреждение, если это возможно, или проигнорировать его для максимальной переносимости.
Если вы хотите перейти к следующему языковому стандарту, это возможно, поскольку были реализованы ссылки rvalue (см. http://russ.yanofsky.org/rref/) поэтому также следует поддерживать std::unique_ptr
.
В свете преимуществ новой семантики вы можете передать конструктору перемещения также временное или любое значение r; в других случаях это позволяет избежать копирования (например) объектов, содержащихся внутри std::vector
(во время перераспределения), прежде чем уничтожить исходные.
Ответ 2
std::unique_ptr
действительно является новым рекомендуемым способом. С контейнерами С++ 0x станет известно о переносе, что означает, что они могут обрабатывать типы, которые правильно перемещаются (т.е. std::vector<std::auto_ptr<x> >
не работает, но std::vector<std::unique_ptr<x>>
будет).
Для boost
контейнеры boost::interprocess
уже поддерживают подвижные типы, где boost::interprocess::unique_ptr
является одним из них. Они напоминают подвижные типы в pre С++ 0x, используя некоторые из "нормальных" мастеров шаблонов boost-template и используют ссылки r-значения там, где они поддерживаются.
Я не знал о auto_ptr
посвященной устареванию, однако, но я не последовал за новой стандартной эволюцией.
(edit) Реализация boost::interprocess::unique_ptr
действительно не является "общедоступным" интеллектуальным указателем, например boost::shared_ptr
или boost::scoped_ptr
, но это (см. сайт boost.interprocess) не только для разделяемой памяти, но также может использоваться для общего назначения.
Тем не менее, я уверен, что если GCC откажется от шаблона auto_ptr
, они уже предоставляют свою собственную реализацию unique_ptr
(мало пользы, чтобы осуждать, если у вас еще нет жизнеспособной альтернативы).
Однако, если все вы сказали, если вы работаете на платформе С++ 0x, используйте unique_ptr
, доступный из библиотеки компилятора, если нет, придерживайтесь auto_ptr
.
Ответ 3
Я согласен, где возможно, вы должны использовать типы, в которых компилятор помогает в передаче прав собственности.
Если у вас нет такого выбора типов данных и передаются исходные указатели, я следую инструкциям по программированию Taligent для методов именования, которые отказываются от владения как orphanBlah и параметры, которые становятся собственностью adoptBlah.
Ответ 4
std:: auto_ptr реализует передачу прав собственности на копию и присвоение, поэтому нет ничего особенного в этом:
std::auto_ptr< T > p = somePtr; // not p owns object, referenced by somePtr
std::auto_ptr< T > q = myObj.GetAutoPtr(); // not q owns object referenced by auto_ptr in myObj
Однако передача собственности объекта не является хорошей практикой проектирования, она ведет к утечкам и относительным ошибкам жизни объекта.
Ответ 5
Я не помню, чтобы std:: auto_ptr устарел.
У кого-нибудь есть ссылка на соответствующую встречу стандартов, где они обсуждают это?
Быстрый поиск Google:
http://objectmix.com/c/113487-std-auto_ptr-deprecated.html
>> In fact the latest publicly available draft lists auto_ptr in appendix
>> D, meaning that there is clear intent to formally deprecate it in the
>> next revision of C++. A new class named unique_ptr is going to provide
>> a replacement for auto_ptr, the main difference being that unique_ptr
>> uses rvalue-references instead of voodoo magic to properly achieve
>> move semantic.
>
> Is a reference implementation available? Is it too early to start using it?
>
In order to use unique_ptr you need first to have a compiler which
properly supports rvalue references. These can be hard to find nowadays,
as the feature has not yet been standardized, although the situation is
quickly improving. For example GCC has very recently added the feature
in v4.3 (http://gcc.gnu.org/gcc-4.3/cxx0x_status.html). If you are lucky
enough to have one of those compilers, most probably they already ship a
version of unique_ptr (it a sort of benchmark for the feature, you
know). In any case, you can find reference implementations on the
internet by just googling unique_ptr.
Таким образом, похоже, что они - это попытки отказаться от auto_ptr в пользу unique_ptr (который имеет ту же семантику). Но ему нужен компилятор, который поддерживает предлагаемые новые функции в предстоящей версии С++.
Но есть еще одна встреча и, таким образом, голосует, чтобы все могло измениться до того, как стандарт станет конкретным.