Implementing CComObject, CComAggObject, and CComPolyObject
The new home for Visual Studio documentation is Visual Studio 2017 Documentation on docs.microsoft.com.
The latest version of this topic can be found at Implementing CComObject, CComAggObject, and CComPolyObject.
The template classes CComObject, CComAggObject, and CComPolyObject are always the most derived classes in the inheritance chain. It is their responsibility to handle all of the methods in IUnknown: QueryInterface
, AddRef
, and Release. In addition, CComAggObject
and CComPolyObject
(when used for aggregated objects) provide the special reference counting and QueryInterface
semantics required for the inner unknown.
Whether CComObject
, CComAggObject
, or CComPolyObject
is used depends on whether you declare one (or none) of the following macros:
Macro | Effect |
---|---|
DECLARE_NOT_AGGREGATABLE |
Always uses CComObject . |
DECLARE_AGGREGATABLE |
Uses CComAggObject if the object is aggregated and CComObject if it is not. CComCoClass contains this macro so if none of the DECLARE_*_AGGREGATABLE macros are declared in your class, this will be the default. |
DECLARE_ONLY_AGGREGATABLE |
Always uses CComAggObject . Returns an error if the object is not aggregated. |
DECLARE_POLY_AGGREGATABLE |
ATL creates an instance of CComPolyObject<CYourClass> when IClassFactory::CreateInstance is called. During creation, the value of the outer unknown is checked. If it is NULL, IUnknown is implemented for a nonaggregated object. If the outer unknown is not NULL, IUnknown is implemented for an aggregated object. |
The advantage of using CComAggObject
and CComObject
is that the implementation of IUnknown is optimized for the kind of object being created. For instance, a nonaggregated object only needs a reference count, while an aggregated object needs both a reference count for the inner unknown and a pointer to the outer unknown.
The advantage of using CComPolyObject
is that you avoid having both CComAggObject
and CComObject
in your module to handle the aggregated and nonaggregated cases. A single CComPolyObject
object handles both cases. This means only one copy of the vtable and one copy of the functions exist in your module. If your vtable is large, this can substantially decrease your module size. However, if your vtable is small, using CComPolyObject
can result in a slightly larger module size because it is not optimized for an aggregated or nonaggregated object, as are CComAggObject
and CComObject
.
See Also
Fundamentals of ATL COM Objects
Aggregation and Class Factory Macros