IUnknown: The Root of All Evil

The IUnknown interface is the one interface that all objects must implement, regardless of what other interfaces are present. IUnknown is what defines object-ness in OLE. An Object's IUnknown pointer value is what gives that object instance its run-time identity. Implementing IUnknown presents little challenge because IUnknown is the base interface for every other interface in OLE. By virtue of implementing any interface, you'll implement IUnknown to boot. In some cases, as we'll see in "Object Polymorphism and Reusability" later in this chapter, you'll need to implement two different sets of IUnknown member functions, but most of the time you'll implement only one set.

This interface itself encapsulates two operations: the control of an object's lifetime (or life cycle, as it is sometimes called, which sounds like a piece of horrendous exercise equipment, so I prefer the first term) and the navigation of multiple interfaces:

IUnknown
Member Function


Result

ULONG AddRef(void)

Increments the object's reference count, returning the new count.

ULONG Release(void)

Decrements the object's reference count, returning the new count. If the new count is 0, the object is allowed to free (delete, destroy) itself, and the caller must then assume that all interface pointers to the object are invalid.

HRESULT QueryInterface

(REFIID riid, void **ppv)

Asks the object whether it supports the interface identified by riid (an IID reference); a return value of NOERROR indicates support exists, and the necessary interface pointer is stored in the out-parameter *ppv. On error, E_NOINTERFACE says the object does not support the interface.


The following sections examine reference counting and QueryInterface in more detail.