Сабж
Насколько (не)оправданно предоставлять из dll виртуальный интерфейс умного указателя?
Допустим, есть интерфейс A (реализация которого владеет массивом объектов B), через который можно получать указатели на объекты B по их именам. Объекта может и не быть в массиве и тогда A вернёт пустой указатель. Имеет ли смысл возвращать вместо него указатель на другой объект с семантикой умного указателя для типов массива B или же разумнее возвращать указатель на сам объект из B и передавать его внутрь уже реализации нашего умного указателя в клиентском коде?
Ну, тогда предположим, что умный указатель возвращается по ссылке, т.к. гарантированно должен быть валиден. Но вопрос не в этом, а в том, есть ли смысл возвращать именно умный указатель вместо сырого?
Да нормальные указатели, если чётко всё обговорить. Возвращать - не плохо. Плохо когда, как в халфе, когда аргумент на строку в движке считается чем-то константным (ну я статью писал). Вот за такое реально ушы отрывать следовало.
Ph03n1x писал: Но вопрос не в этом, а в том, есть ли смысл возвращать именно умный указатель вместо сырого?
Возвращать умный указатель из другого модуля в общем случае нельзя. Хотя бы потому, что в дебаге и релизе они могут быть разными, и ты ставишь пользователя библиотеки в зависимость от типа сборки. То же касается STL-контейнеров, хэндлов и т.п. Всё это, имхо, плохой дизайн.
Он в виде указателя на виртуальный интерфейс передаётся, в том и фишка
Но проблема может возникнуть в другом - либо на каждый IFoo* свой ISmartFoo*, либо один общий, через который, как через бутылочное горлышко, происходит взаимодействие со всеми IFoo*. Ну и есть вариант завести пул умных указателей, что, как по мне, ненужное усложнение. Думаю, что лучше всего - оставить как есть и выдавать указатель на IFoo*, а на другой стороне заворачивать в смарт
Ph03n1x
Ещё раз - зачем тут смарты?
Когда спрашивают про возвращение смарта из библиотеки, я представляю что-то вроде такого:
C++ Source Code:
shared_ptr<Foo> get_data( int my_arg )
{
return shared_ptr<Foo>( new Foo( my_arg ) );
}
А это превращает код в implementation-specific, потому что нет никакой гарантии, что вызывающий код использует точно такой же shared_ptr, что и библиотека. Например, библиотека использовала std::shared_ptr, а пользовательский код использует boost::shared_ptr.
XaeroX
Как раз таки этого я и избегаю, т.к. причину ты сам указал
А я про кастомный смарт, оформленный в виде виртуального интерфейса и не затрагивающий ничего импл-зависимого
Чтобы не нужно было каждый раз проверять на валидность + возвращать дефолтные значения (хардкодные или указанные в арг-ах к функции)