Какова цель функций-членов IUnknown в END_COM_MAP?

Макрос ATL END_COM_MAP определяется следующим образом:

#define END_COM_MAP() \
    __if_exists(_GetAttrEntries) {{NULL, (DWORD_PTR)_GetAttrEntries, _ChainAttr }, }\
    {NULL, 0, 0}}; return _entries;} \
    virtual ULONG STDMETHODCALLTYPE AddRef( void) throw() = 0; \
    virtual ULONG STDMETHODCALLTYPE Release( void) throw() = 0; \
    STDMETHOD(QueryInterface)(REFIID, void**) throw() = 0;

Он предназначен для использования в определении классов, унаследованных от COM-интерфейсов, например:

class ATL_NO_VTABLE CMyClass :
    public CComCoClass<CMyClass, &MyClassGuid>,
    public CComObjectRoot,
    public IMyComInterface
{
public:
    BEGIN_COM_MAP( CMyClass )
        COM_INTERFACE_ENTRY( IMyComInterface)
    END_COM_MAP()
};

Это означает, что QueryInterface (), AddRef () и Release () объявлены в этом классе как чисто виртуальные. Поскольку я не определяю их реализацию, этот класс не должен быть создан. Тем не менее, ATL успешно его инстанцирует.

Как это работает и почему здесь повторно объявлены функции-члены IUnknown?


person sharptooth    schedule 13.11.2009    source источник


Ответы (1)


Прошло некоторое время с тех пор, как я использовал ATL, но IIRC создает экземпляр не CMyClass, а CComObject<CMyClass>.

CComObject реализует IUnknown и наследуется от своего параметра шаблона.

Изменить: страница "Основы COM-объектов ATL" в MSDN красиво иллюстрирует, что происходит.

person Éric Malenfant    schedule 13.11.2009
comment
И есть множество других CComObject, как упоминалось в упомянутой статье. Каждый вариант настраивает поведение IUnknown, либо QueryInterface, либо управление временем жизни (AddRef / Release). - person Kim Gräsman; 14.11.2009