Containment/delegation allows some flexibility. For example, when the outer object exposes the same interface as the inner object, it can filter calls to the inner object by manipulating the method's parameters or augmenting the inner object's results.
The outer object can also choose not to delegate a call to the inner object.
For example, depending on a dynamic data set, OuterCOMObj's implementation of IX1::x1 may not call InnerCOMObj's implementation of IX1::x1.
Another variation of containment/delegation is that the outer object does not expose the same interface as the inner object. Instead, it delegates to methods in the inner COM object from a different interface.
For example, instead of implementing IX1, OuterCOMObj implements ZZ1 with methods z1 and z2.
In ZZ1::z1, OuterCOMObj delegates by calling InnerCOMObjIX1::x2.
COM containment is similar to C++ containment.
The outer component is simply a client of the inner components. The outer component implements its own interfaces using the inner components.
The clients of the outer component do not know that the outer component uses other components to carry out its services.
The outer component can also re-implement an interface supported by an inner component by forwarding calls to the inner component. The outer component might specialize the interface by adding scode before and after the code for the inner component.