HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Технические вопросы (https://hlfx.ru/forum/forumdisplay.php?forumid=20)
-- [C++] Виртуальный умный указатель?! (https://hlfx.ru/forum/showthread.php?threadid=4886)
Отправлено Ph03n1x 12-11-2016 в 17:30:
[C++] Виртуальный умный указатель?!
Сабж
Насколько (не)оправданно предоставлять из dll виртуальный интерфейс умного указателя?
Допустим, есть интерфейс A (реализация которого владеет массивом объектов B), через который можно получать указатели на объекты B по их именам. Объекта может и не быть в массиве и тогда A вернёт пустой указатель. Имеет ли смысл возвращать вместо него указатель на другой объект с семантикой умного указателя для типов массива B или же разумнее возвращать указатель на сам объект из B и передавать его внутрь уже реализации нашего умного указателя в клиентском коде?
Отправлено XaeroX 12-11-2016 в 17:45:
Ничего не понял в описанном, но могу сказать наверняка: возвращение любых указателей, хоть умных, хоть глупых, это признак плохого дизайна.
__________________
Отправлено Ph03n1x 12-11-2016 в 17:53:
Ну, тогда предположим, что умный указатель возвращается по ссылке, т.к. гарантированно должен быть валиден. Но вопрос не в этом, а в том, есть ли смысл возвращать именно умный указатель вместо сырого?
Отправлено Дядя Миша 12-11-2016 в 19:01:
Да нормальные указатели, если чётко всё обговорить. Возвращать - не плохо. Плохо когда, как в халфе, когда аргумент на строку в движке считается чем-то константным (ну я статью писал). Вот за такое реально ушы отрывать следовало.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено XaeroX 12-11-2016 в 19:10:
Цитата:
Ph03n1x писал:
Но вопрос не в этом, а в том, есть ли смысл возвращать именно умный указатель вместо сырого?
Возвращать умный указатель из другого модуля в общем случае нельзя. Хотя бы потому, что в дебаге и релизе они могут быть разными, и ты ставишь пользователя библиотеки в зависимость от типа сборки. То же касается STL-контейнеров, хэндлов и т.п. Всё это, имхо, плохой дизайн.__________________
Отправлено Ph03n1x 12-11-2016 в 19:28:
Он в виде указателя на виртуальный интерфейс передаётся, в том и фишка
Но проблема может возникнуть в другом - либо на каждый IFoo* свой ISmartFoo*, либо один общий, через который, как через бутылочное горлышко, происходит взаимодействие со всеми IFoo*. Ну и есть вариант завести пул умных указателей, что, как по мне, ненужное усложнение. Думаю, что лучше всего - оставить как есть и выдавать указатель на IFoo*, а на другой стороне заворачивать в смарт
Отправлено nemyax 12-11-2016 в 19:31:
Цитата:
XaeroX писал:
Всё это, имхо, плохой дизайн.
А хороший какой? Передача указателя аргументом функции на in-place обработку?
Отправлено XaeroX 12-11-2016 в 19:33:
Цитата:
nemyax писал:
А хороший какой? Передача указателя аргументом функции на in-place обработку?
Полагаю, что да.
Цитата:
Ph03n1x писал:
на другой стороне заворачивать в смарт
Зачем?__________________
Отправлено Ph03n1x 12-11-2016 в 19:56:
Цитата:
XaeroX писал:
nemyax писал:
Передача указателя аргументом функции на in-place обработку?
А зачем, если у нас указатель не на структуру, а на вирт.интерфейс?
C++ Source Code:
7 | void DoABarrelRoll(struct barrel *pbarrel) |
12 | // Я предоставляю указатель на ООП-интерфейс |
15 | virtual void DoARoll() = 0; |
18 | class CBarrel : public IBarrel |
21 | void DoARoll(){rolls++;} |
28 | virtual IBarrel *GetBarrel() = 0; |
31 | IBarrelProvider *gpBarrelProvider = GetBarrelProvider(); |
32 | gpBarrelProvider->GetBarrel()->DoARoll(); // если бочку получать в виде смарта, то можно обращаться прямо так |
Отправлено XaeroX 12-11-2016 в 20:46:
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.__________________
Отправлено Ph03n1x 12-11-2016 в 21:00:
XaeroX
Как раз таки этого я и избегаю, т.к. причину ты сам указал
А я про кастомный смарт, оформленный в виде виртуального интерфейса и не затрагивающий ничего импл-зависимого
Чтобы не нужно было каждый раз проверять на валидность + возвращать дефолтные значения (хардкодные или указанные в арг-ах к функции)
C++ Source Code:
1 | IFoo *pFoo = pFooProvider->GetFoo("abc"); |
5 | IFooRef *pFooRef = pFooProvider->GetFooRef("abc"); |
6 | int nBar = pFooRef->GetBar(); |
8 | class CFooRef : public IFooRef |
11 | void Set(IFoo *apFoo){mpFoo = apFoo;} |
12 | IFoo *Get(){return mpFoo;} |
14 | int GetBar(/*int nDefBar*/) |
17 | return mpFoo->GetBar(); |