HLFX.Ru Forum
Показать все 11 сообщений этой темы на одной странице

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:

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

__________________

xaerox on Vivino


Отправлено 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-контейнеров, хэндлов и т.п. Всё это, имхо, плохой дизайн.

__________________

xaerox on Vivino


Отправлено 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 писал:
на другой стороне заворачивать в смарт

Зачем?

__________________

xaerox on Vivino


Отправлено Ph03n1x 12-11-2016 в 19:56:

Цитата:
XaeroX писал:
nemyax писал:
Передача указателя аргументом функции на in-place обработку?


А зачем, если у нас указатель не на структуру, а на вирт.интерфейс?

C++ Source Code:
1
// Вы предлагаете так?
2
struct barrel
3
{
4
  int rolls;
5
};
6
 
7
void DoABarrelRoll(struct barrel *pbarrel)
8
{
9
  pbarrel->rolls++;
10
};
11
 
12
// Я предоставляю указатель на ООП-интерфейс
13
struct IBarrel
14
{
15
  virtual void DoARoll() = 0;
16
};
17
 
18
class CBarrel : public IBarrel
19
{
20
public:
21
  void DoARoll(){rolls++;}
22
private:
23
  int rolls;
24
};
25
 
26
struct IBarrelProvider
27
{
28
  virtual IBarrel *GetBarrel() = 0;
29
};
30
 
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.

__________________

xaerox on Vivino


Отправлено Ph03n1x 12-11-2016 в 21:00:

XaeroX
Как раз таки этого я и избегаю, т.к. причину ты сам указал

А я про кастомный смарт, оформленный в виде виртуального интерфейса и не затрагивающий ничего импл-зависимого
Чтобы не нужно было каждый раз проверять на валидность + возвращать дефолтные значения (хардкодные или указанные в арг-ах к функции)

C++ Source Code:
1
IFoo *pFoo = pFooProvider->GetFoo("abc");
2
if(!pFoo)
3
  NULL_PTR_ALARM();
4
 
5
IFooRef *pFooRef = pFooProvider->GetFooRef("abc");
6
int nBar = pFooRef->GetBar();
7
 
8
class CFooRef : public IFooRef
9
{
10
public:
11
  void Set(IFoo *apFoo){mpFoo = apFoo;}
12
  IFoo *Get(){return mpFoo;}
13
 
14
  int GetBar(/*int nDefBar*/)
15
  {
16
    if(mpFoo)
17
      return mpFoo->GetBar();
18
 
19
    return 0; // nDefBar
20
  };
21
private:
22
  IFoo *mpFoo;
23
};


Временная зона GMT. Текущее время 11:00.
Показать все 11 сообщений этой темы на одной странице

На основе vBulletin версии 2.3.0
Авторское право © Jelsoft Enterprises Limited 2000 - 2002.
Дизайн и программирование: Crystice Softworks © 2005 - 2024