Что нужно для AtlComPtrAssign? - PullRequest
       46

Что нужно для AtlComPtrAssign?

2 голосов
/ 21 февраля 2012

В настоящее время CComPtr::operator= реализовано с использованием вспомогательной функции AtlComPtrAssign(), которая имеет следующую подпись:

IUnknown* AtlComPtrAssign( IUnknown** pp, IUnknown* lp);

и должен называться так:

T* operator=( const CComPtr<T>& lp) throw()
{
    if(*this!=lp) {
        return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp));
    }
    return *this;
}

, который вызывает проблемы, если я пытаюсь сохранить использование CComPtr с T, являющимся классом, реализующим более одного интерфейса COM - преобразование в IUnknown* становится неоднозначным, и компиляция завершается неудачей.

Мой вопрос - зачем использовать такую ​​вспомогательную функцию, которая имеет именно эти параметры? Почему бы не сделать так:

template<classT>
T* AtlComPtrAssign( T** pp, T* lp);

и назовите это для любого разумного T? Зачем нужен этот подъем до IUnknown*, а затем обратный переход до T*?

1 Ответ

1 голос
/ 21 февраля 2012
  1. Аргумент шаблона для CComPtr <> - это интерфейс, а не полный класс, поэтому вы не можете иметь несколько IUnknown s, всегда есть только один.
  2. Я бы предположил, что вся история AtlComPtrAssign состоит в том, что в первые дни функция необязательно находилась в ATL.DLL, если только при выборе определенных опций не было бы предпочтения статическая ссылка на ATL.

Я считаю, что с более ранними версиями ATL вы могли бы использовать CComPtr также с классом. Я помню, как использовал его, и это было очень удобно - у вас мог быть как автоматический подсчет ссылок, так и необработанный указатель класса (в отличие от указателя интерфейса), но в какой-то момент такое использование было недоступно из-за ошибок компилятора, и для этого понадобился бы собственный шаблон класс вместо стандартного CComPtr для достижения той же функциональности.

...