IUnknown and Interface Definition Inheritance

Inheritance in COM does not mean code reuse. Because no implementations are associated with interfaces, interface inheritance does not mean code inheritance. It means only that the contract associated with an interface is inherited in a C++ pure-virtual base-class fashion and modified &emdash; either by adding new methods or by further qualifying the allowed usage of methods. There is no selective inheritance in COM: If one interface inherits from another, it includes all the methods that the other interface defines.

Inheritance is used sparingly in the predefined COM interfaces. All predefined interfaces (and any custom interfaces you define) inherit their definitions from the important interface IUnknown, which contains three vital methods: QueryInterface, AddRef, and Release. All COM objects must implement the IUnknown interface, because it provides the means to move freely between the different interfaces that an object supports with QueryInterface, and to manage its lifetime with AddRef and Release. More on these methods is discussed later in this chapter.

Any single object usually requires only a single implementation of the IUnknown methods. This means that by implementing any interface on an object you must completely implement the IUnknown functions. You do not generally need to explicitly inherit from nor implement IUnknown as its own interface. When a client of the object queries for it, it is usually necessary only to typecast another interface pointer into an IUnknown, as this interface makes up the first three entries in the function table already.

In some specific situations, notably in creating an object that supports aggregation, you may need to implement one set of IUnknown functions for all interfaces as well as a stand-alone IUnknown interface. This is described in the following section. In any case, any object implementor will implement IUnknown methods. Refer to the section Using and Implementing IUnknown for more information.

While there are a few interfaces that inherit their definitions from a second interface, in addition to IUnknown, the majority are simply the IUnknown interface methods plus the methods defined in the interface. This makes most interfaces relatively compact and easy to encapsulate.