Aggregation
Go Up to Reusing Code and Delegation
Aggregation offers a modular approach to code reuse through sub-objects that make up the functionality of a containing object, but that hide the implementation details from that object. In aggregation, an outer object implements one or more interfaces. At a minimum, it must implement IInterface. The inner object, or objects, also implement one or more interfaces. However, only the outer object exposes the interfaces. That is, the outer object exposes both the interfaces it implements and the ones that its contained objects implement.
Clients know nothing about inner objects. While the outer object provides access to the inner object interfaces, their implementation is completely transparent. Therefore, the outer object class can exchange the inner object class type for any class that implements the same interface. Correspondingly, the code for the inner object classes can be shared by other classes that want to use it.
The aggregation model defines explicit rules for implementing IInterface using delegation. The inner object must implement two versions of the IInterface methods.
- It must implement IInterface on itself, controlling its own reference count. This implementation of IInterface tracks the relationship between the outer and the inner object. For example, when an object of its type (the inner object) is created, the creation succeeds only for a requested interface of type IInterface.
- It also implements a second IInterface for all the interfaces it implements that the outer object exposes. This second IInterface delegates calls to QueryInterface, _AddRef, and _Release to the outer object. The outer IInterface is referred to as the "controlling Unknown."
Refer to the MS online help for the rules about creating an aggregation. When writing your own aggregation classes, you can also refer to the implementation details of IInterface in TComObject. TComObject is a COM class that supports aggregation. If you are writing COM applications, you can also use TComObject directly as a base class.