Основными причинами являются отрывные интерфейсные указатели (например, для редко используемых интерфейсов) и агрегируемые объекты (COM-эквивалент mixins, более или менее).
В этих случаях (отрыв или агрегатор при запросе на агрегированный IID) ppv
не является указателем интерфейса на тот же объект C++ с подсчетом ссылок. Таким образом, этот код необходим, если вы хотите также поддерживать эти случаи.
Позвонив по телефону this->AddRef
, возможно, вы получаете немного простоты или типа безопасности, но за счет отсутствия поддерживающих интерфейсов, явно не реализованных одним и тем же объектом C++.
P.S .: Вопреки тому, что большинство книг и документации, на мой взгляд:
- Aggregation больше похоже на использование Примеси, чем на наследование или композицию;
- Агрегация на самом деле является особым случаем (кэшированных) отрывных указателей интерфейса в отличие от специального случая композиции.
Вот моя линия мысли:
- При наследовании, вы обычно имеете возможность переопределения (виртуальные) методы, что не так с агрегацией из-за прямой метод вызывает; когда вы используете композицию, вам может потребоваться обернуть входящие объекты, чтобы не допустить, чтобы внутренний объект теряет свою идентичность с данным объектом (например, внутренний объект может передать себя некоторому методу входящего объекта), тогда как агрегирование также означает совместное использование имеющих два набора методов
IUnknown
на агрегируемых объектах, таким образом не имея этой конкретной проблемы вообще;
- Отрыв имеет собственное время жизни, тогда как агрегируемый объект делится своей жизнью с внешним объектом. В противном случае либо может создаваться только при необходимости, хотя агрегаторы обычно создают агрегируемые объекты, как только они сами создаются.
Если интерфейс-> AddRef отображает это-> AddRef, то, полагаю, вы могли бы просто использовать 'this', но так ли это всегда? –
@ 500-InternalServerError: Предположим, что вышеуказанный код является частью некоторой реализации COM-объекта, например 'class CSomeComponent: public IInterface1, public IInterface2 {...};'. Что было бы неправильно с простым 'AddRef();' call, а не 'static_cast (* ppv) -> AddRef();' call? –
BTW: В [этой статье MSDN] (http://msdn.microsoft.com/en-us/magazine/dn879357.aspx) - в соответствии с вышеупомянутым шаблоном вызова AddRef - он читает, что _ "[...] AddRef is вызывается через результирующий указатель интерфейса снова, чтобы поддерживать некоторые редкие, но допустимые сценарии составления классов «_. Интересно, каковы эти сценарии и каковы технические причины этого метода addRef() «call-style» ... –