2010-03-15 2 views
0

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

Правильно ли это реализация?

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

ответ

0

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

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

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

или

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

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

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

+1

+1 Я забыл упомянуть в своем ответе о важности интерфейса, помогающего с семантикой: 'auto_ptr' подразумевает передачу права собственности. –

+0

auto_ptr - это зло, особенно когда вы непреднамеренно передаете их по значению ... boost :: scoped_ptr намного лучше в этом отношении. –

+2

@Alexandre C .: Для этого использования 'boost :: scoped_ptr' совершенно неуместно. Поскольку он не копируется, его нельзя даже использовать как возвращаемое значение. 'std :: auto_ptr' не является злом так же, как бензопила не является злом. Это просто инструменты; у них нет намерений.Просто потому, что жонглирование бензопилой очень опасно, не означает, что у них нет полезного приложения: вырубка деревьев. Существуют более стандартные способы выражения передачи права собственности в C++ 0x (например, unique_ptr - хотя, возможно, лучший интерфейс возможен только благодаря rvalue-ссылкам), но здесь по крайней мере 'std :: auto_ptr'. –

2

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

Если память фактически не используется, я бы не использовал 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

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

 Смежные вопросы

  • Нет связанных вопросов^_^