dynamic_cast COM-объекта в COM-интерфейс не влияет на счетчик ссылок, не так ли?

Если у меня есть класс C++, X, который реализует интерфейсы COM IY и IZ, и у меня есть указатель y на интерфейс IY объекта типа X, и я делаю это:

IZ *z = dynamic_cast<IZ *> ( y );

Это не влияет на счетчик ссылок объекта, не так ли? Мне не нужно делать Release(), чтобы объяснить это, верно?

Если это имеет значение, я использую ATL/COM.

Я предполагаю, что ответ "нет, это не увеличивает счетчик ссылок, и нет, вы не обязаны выпускать ()", но я хочу убедиться.

Заранее спасибо.

3 ответа

Решение

Подсчет ссылок для COM-объектов увеличивается, когда кто-то вызывает IUnknown::AddRef(). QueryInterface(), в соответствии с правилами COM, поскольку он выдает новый указатель интерфейса, внутренне вызывает AddRef ().

В своем опубликованном коде вы не вызываете AddRef () и не вызываете функцию, которая может вызывать AddRef (), так почему вы думаете, что счетчик ссылок будет увеличен?

Несмотря на то, что ATL/MFC делает с мозгом, в этом нет никакой магии. Если вы сомневаетесь, вы всегда можете просмотреть разборку в VS, пройтись по ней и доказать себе, что AddRef () не вызывается.

Редактировать: И я хочу повторить то, что сказал Дьюфи, не делай этого. Используйте QueryInterface(). Или CComQIPtr<> (если вы действительно должны).

Дальнейшее редактирование: если вы используете CComPtr<> и CComQIPtr <>, то вам не нужно вызывать Release(), и большая часть бремени выяснения правильного подсчета ссылок уменьшается. Вы должны действительно рассмотреть возможность их использования.

dynamic_cast не должен использоваться по нескольким причинам:

  • Вы не знаете, поддерживает ли пункт назначения RTTI
  • Вы не уверены, что OLE не создает прокси для вас
  • ...

Вместо этого используйте QueryInterface - он будет делать то, что вы хотите.

Даже если вы уверены, что в вопросе выше - кастинг не меняет refcounter

В C++Builder dynamic_cast на указателе интерфейса COM на самом деле QueryInterface, и возвращенный указатель, если QI успешно, получает AddRef"D.

Классы, которые реализуют COM-объекты, имеют различные макеты vtable по сравнению с более общими классами C++, поэтому стиль C++ dynamic_cast не может работать; поэтому я предполагаю, что именно поэтому C++Builder делает более разумную работу QueryInterface.

(Первоначальная идея COM заключалась в том, чтобы обобщить объектную модель C++, чтобы она не зависела от языка и соответствовала двоичному стандарту; они переименовали dynamic_cast в QueryInterface).

Я думаю, что верхний ответ относится к MSVC, если dynamic_cast вызывает неопределенное поведение.

Другие вопросы по тегам