Реализация CComObject, CComAggObject и CComPolyObject
Классы шаблонов CComObject, CComAggObject и CComPolyObject всегда являются наиболее производными классами в цепочке наследования. Это их ответственность за обработку всех методов в IUnknown
: QueryInterface
, AddRef
и Release
. Кроме того, CComAggObject
и CComPolyObject
(при использовании для агрегированных объектов) предоставляют специальное подсчет ссылок и QueryInterface
семантику, необходимые для внутреннего неизвестного.
CComAggObject
CComPolyObject
Независимо CComObject
от того, используется ли он или используется, следует ли объявлять один (или нет) следующих макросов:
Макрос | Действие |
---|---|
DECLARE_NOT_AGGREGATABLE | Всегда используется CComObject . |
DECLARE_AGGREGATABLE | Используется CComAggObject , если объект агрегирован и CComObject если он отсутствует. CComCoClass содержит этот макрос, поэтому если ни один из макросов DECLARE_*_AGGREGATABLE объявлен в классе, это будет значение по умолчанию. |
DECLARE_ONLY_AGGREGATABLE | Всегда используется CComAggObject . Возвращает ошибку, если объект не агрегирован. |
DECLARE_POLY_AGGREGATABLE | ATL создает экземпляр CComPolyObject<CYourClass> при IClassFactory::CreateInstance вызове. Во время создания проверяется значение внешнего неизвестного. Если значение NULL, IUnknown реализуется для негрегатированного объекта. Если внешний неизвестный не имеет значения NULL, IUnknown реализуется для агрегированного объекта. |
Преимущество использования CComAggObject
и CComObject
заключается в том, что реализация IUnknown
оптимизирована для типа создаваемого объекта. Например, негрегатированный объект нуждается только в подсчете ссылок, в то время как агрегатный объект нуждается как в счетчике ссылок для внутреннего неизвестного, так и указателя на внешний неизвестный.
Преимущество использования CComPolyObject
заключается в том, что вы избегаете использования как CComAggObject
в модуле, так и CComObject
в модуле для обработки агрегированных и негрегатированных случаев. Один CComPolyObject
объект обрабатывает оба случая. Это означает, что в модуле существует только одна копия vtable и одна копия функций. Если vtable большой, это может значительно уменьшить размер модуля. Тем не менее, если ваша vtable небольшая, использование CComPolyObject
может привести к немного большему размеру модуля, так как он не оптимизирован для агрегированного или негрегатированного объекта, как и CComObject
CComAggObject
.
См. также
Основы COM-объектов ATL
Макросы агрегирования и фабрик классов