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 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 the DECLARE_POLY_AGGREGATABLE macro and on whether your object is being aggregated:

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.

The DECLARE_POLY_AGGREGATABLE macro is automatically added to your class definition by the ATL Object Wizard when you create a full control or Internet Explorer control. For more information about the wizard, see Creating an ATL Project.