2011-01-20 2 views
5

Я хотел бы знать, что в настоящее время рассматривается в передовой практике при возвращении указателя на полиморфный объект из функции, например, при использовании заводов. Если я передам право собственности, должен ли я вернуть boost::unique_ptr<Interface>? Что я должен вернуть, если я не передаю право собственности (например, верну ссылку на член)? Существует ли альтернативный, не основанный на усилении способ, который также широко используется? Благодарю.Возвращаемые полиморфные объекты C++ (интерфейсы)

EDIT: он должен быть C++ 03 совместимо с возможностью легко обновить до 0x

EDIT2: Пожалуйста, обратите внимание, что я явно прошу о общих подходов, лучшие практиками, а не только «способ сделать это». Решение, подразумевающее условный поиск и замену над кодовой базой в будущем, не похоже на хорошую практику, не так ли?

EDIT3: Еще один момент, касающийся auto_ptr, заключается в том, что он - это, который не рекомендуется, независимо от того, насколько он чист, поэтому странно рекламировать его использование на уровне интерфейса. Затем кто-то не знает, вернет ли указатель в контейнер STL и т. Д. И т. Д. Поэтому, если вы знаете другое как-то общее решение, вы можете добавить ответ.

+0

Вы можете пожаловаться на все, что хотите, о том, как ':: std :: auto_ptr' устарел, факт: вы не можете сделать лучше без накладных расходов или сужения интерфейса. Если вы используете ':: std :: tr1 :: shared_ptr', вы получаете подсчет ссылок, когда он вам не нужен. Действительно, ':: std :: auto_ptr' - единственное разумное решение, доступное в C++. ':: boost :: unique_ptr' просто удаляет проблемные операции из' :: std :: auto_ptr'. И хотя некоторые могут подумать, что это лучше, это сторонняя библиотека, и я не могу рекомендовать использование сторонней библиотеки как «лучшей практики», если не будет альтернативы. – Omnifarious

+0

@ Omnifarious: Я ценю, что вы отвечаете, но я также пытаюсь побудить других людей поделиться своим мнением. –

+0

Есть ли причина, по которой вы не рассматриваете 'shared_ptr' для этого? –

ответ

5

На данный момент используйте ::std::auto_ptr, а когда доступен C++ 0x, переключитесь на ::std::unique_ptr. По крайней мере, в заводском случае, когда вы передаете права собственности вызывающему.

Да ::std::auto_ptr имеет проблемы и является уродливым. Да, он устарел в C++ 0x. Но это рекомендуемый способ сделать это. Я не изучил ::boost::unique_ptr, но без семантики перемещения я не вижу, что он может сделать лучше, чем ::std::auto_ptr.

Я предпочитаю модернизацию, выполняя поиск и замену, хотя есть некоторые необычные случаи, когда у этого не будет ожидаемого результата. К счастью, такие случаи возникают ошибки компилятора:

::std::auto_ptr<int> p(new int); 
::std::auto_ptr<int> p2 = p; 

должен стать, по крайней мере, как этого

::std::unique_ptr<int> p(new int); 
::std::unique_ptr<int> p2 = ::std::move(p); 

Я предпочитаю поиск и замену, потому что я считаю, что с помощью макросов и определений типов для таких вещей, как это, как правило, делает вещи более неясные и трудно понять позже. Поиск и замена вашей кодовой базы можно применять выборочно, если это необходимо (::std::auto_ptr не исчезнет в C++ 0x, это просто устарело) и оставляет ваш код ясным и очевидным намерением.

Что касается того, что «обычно» сделано, я не думаю, что проблема была вокруг достаточно долго, чтобы быть общепринятым методом обработки перехода.

+2

+1 - 'std :: auto_ptr' является удивительным, несмотря на то, что люди все время его избивают. –

+0

Ну, но как мне переключиться на него, путем поиска и замены всего кода? –

+0

@ 7vies: Предполагая, что зависимость повышения не является проблемой, просто продолжайте использовать boost, за исключением случаев, когда вы должны передать право собственности. В противном случае вам придется выполнять поиск и замену. –