Кажется, есть небольшое недоразумение.Интерфейсы IInterface1
и IInterface2
являются абстрактными.Не существует отдельных QueryInterface()
для IInterface1
и IInterface2
.Есть только объявление, что класс CMyClass
будет реализовывать все методы из IInterface1
и IInterface2
(набор методов CMyClass
- это набор методов IInterface1
и IInterface1
вместе).
Таким образом, вы реализуете в классе CMyClass
one QueryInterface()
, one AddRef()
и one Release()
метод.В QueryInterface()
вы приводите указатель на экземпляр класса CMyClass
в static_cast<IUnknown*>
.
ОБНОВЛЕНО : Привет!Мне пришлось уехать сразу после написания моего ответа.Только теперь я смог прочитать все остальные ответы и что-то добавить к своему ответу.
ОК.Вы говорите, что если вы разыгрываете IInterface1
на IUnknown
и если вы разыгрываете IInterface2
на IUnknown
, вы получаете два разных указателя.Вы правы!Но тем не менее это не имеет значения.Если вы сравните содержимое обоих указателей (адреса которых имеют QueryInterface()
, AddRef()
и Release()
в обоих случаях), вы увидите, что оба указателя имеют одинаковое содержимое.Так что я тоже прав!
Есть много хороших примеров того, как реализовать COM в чистом C. В этом случае вам нужно определить статические структуры с указателями на виртуальные функции, такие как QueryInterface()
, AddRef()
и Release()
и вернуть указатель такой структуры в результате QueryInterface()
.Это еще раз показывает, что для COM важно только содержимое, которое вы возвращаете, а не указатель (не важно, какой vtable вы возвращаете).
Еще одно небольшое замечание.В некоторых комментариях вы пишете о возможности иметь много реализаций методов QueryInterface()
, AddRef()
и Release()
.Я не согласен здесь.Причина в том, что интерфейсы являются чисто абстрактными классами , и если вы определяете класс, который реализует некоторые интерфейсы, у вас нет типичного наследования классов.У вас есть только один класс с одной реализацией всех функций из всех интерфейсов .Если вы сделаете это в C ++, то компилятор создаст и заполнит статические vtables соответствующими указателями на единственную реализацию функций QueryInterface()
, AddRef()
, Release()
и т. Д., Но все vtables указывают на одни и те же функции.
Чтобы уменьшить количество vtables, Microsoft представила __declspec(novtable)
или ATL_NO_VTABLE
, но это не часть ваших вопросов.