Предположим, у меня есть класс, реализующий два или более COM интерфейсов (точно так, как here):Использует неявное преобразование для upcast вместо QueryInterface() с множественным наследованием?
class CMyClass : public IInterface1, public IInterface2 {
};
QueryInterface()
должен возвращать тот же указатель для каждого запроса одного и того же интерфейса (требуется явное вентиляционный для правильной настройки указателя) :
if(iid == __uuidof(IUnknown)) {
*ppv = static_cast<IInterface1*>(this);
//call Addref(), return S_OK
} else if(iid == __uuidof(IInterface1)) {
*ppv = static_cast<IInterface1*>(this);
//call Addref(), return S_OK
} else if(iid == __uuidof(IInterface2)) {
*ppv = static_cast<IInterface2*>(this);
//call Addref(), return S_OK
} else {
*ppv = 0;
return E_NOINTERFACE;
}
теперь вы два IUnknown
с в объекте - один является базой IInterface1
, а другой является основой IInterface2
. И .
Давайте представим, что я назвал QueryInterface()
для IInterface2
- указатель, возвращаемый будет отличаться от указателя возвращается, когда я называю QueryInterface()
для IUnknown
. Все идет нормально. Затем я могу передать полученный IInterface2*
в любую функцию, принимающую IUnknown*
, и благодаря неявному преобразованию C++ указатель будет принят, но это будет не тот указатель, который будет получать QueryInterface()
для IUnknown*
. Фактически, если эта функция вызывает QueryInterface()
для IUnknown
сразу после ее вызова, она будет извлекать другой указатель.
Является ли это законным с точки зрения COM? Как мне обрабатывать ситуации, когда у меня есть указатель на многократно унаследованный объект, и я допускаю неявное повышение?
Практически говоря, я никогда не видел, чтобы какой-либо код использовал правила COM-идентификации. Тем не менее, другой IUnknown * НЕ является законным - вы ДОЛЖНЫ выбрать один для возврата из QueryInterface. С точки зрения вашего собственного внутреннего использования на C++ объекта, реализующего объект COM, - если вы производите произвольное выполнение COM, так что все, что вы делаете, является законным C++, но не легитимирует COM. –
@ Крис Бекке: Я думаю, что для реализации некоторых функций, подобных кешу, требуется идентификация. – sharptooth