Как правильно убедиться, что пользователь использует shared_ptr, а не обычный ptr? - PullRequest
0 голосов
/ 15 марта 2010

В моем классе конструктор является приватным, и я добавил статический метод "CreateMyClassPtr", который использует конструктор и возвращает его share_ptr.

Это правильная реализация?

Как вы думаете, мне даже нужно убедиться, что shared_ptr будет использоваться? Должен ли я оставить это на усмотрение пользователя?

Ответы [ 4 ]

3 голосов
/ 15 марта 2010

Если вы не держите его копии, но хотите, чтобы пользователь удалил указатель на объект с помощью delete, вы можете вернуть std::auto_ptr по значению. Он не добавляет никаких зависимостей (auto_ptr является частью стандарта) и позволяет вашему интерфейсу четко сообщать о том, что объект должен быть delete d.

Если пользователь хочет, то он может release указать указатель и сделать что-то вручную или переместить его в свою общую инфраструктуру интеллектуального указателя.

2 голосов
/ 15 марта 2010

Действительно ли элемент является общим? То есть после создания вы сохраняете указатель на объект для своих собственных целей или делаете это просто для того, чтобы избежать утечек пользовательской памяти?

Если память фактически не используется совместно, я бы не использовал shared_ptr. Обратите внимание, что используя shared_ptr в качестве возвращаемого типа, вы заставляете использовать как динамическое выделение, так и конкретную реализацию интеллектуального указателя, но ограничивает использование стека для вашего типа и других типов интеллектуальных указателей, которые могут быть более подходящими ( вы не можете извлечь членство из общего указателя)

Если вы действительно хотите убедиться, что вызов не протекает (то есть, если пользователь вызывает вашу функцию, то возвращенная память будет обработана «как-то», вы можете использовать std::auto_ptr или boost::unique_ptr (последний) будучи нестандартным даже в C ++ 0x.) Оба решения позволяют вызывающему коду извлекать указатель из интеллектуального указателя и использовать другой подход к управлению памятью (даже если в некоторых случаях это может быть громоздким).

struct type {
   std::auto_ptr<type> create(); 
};
std::auto_ptr<type> ap = type::create();
std::shared_ptr<type> sp( type::create().release() );
type::create(); // will not leak memory
type *rp = type::create().release(); // user specifically requested a raw pointer!
1 голос
/ 15 марта 2010

Это сработает, да. Тем не менее, вы уверены, что вам это нужно? Есть обстоятельства, когда это уместно, но вы действительно ограничиваете свои возможности, когда делаете это. Существуют и другие формы интеллектуальных указателей, которые пользователи могут захотеть использовать, не говоря уже о том, что вы исключаете размещение на основе стека в качестве опции, когда вы таким образом скрываете свои конструкторы.

0 голосов
/ 15 марта 2010

Если вы собираетесь предоставлять свой класс клиентам, не заставляйте их использовать общие указатели. Они знают, что создают объект, и несут ответственность за его удаление.

Они тогда легко могут написать

myfavorite::api::shared_ptr<Class> object(Class::create());

или

std::auto_ptr<Class> object(Class::create());
...