From Learning DCOM by Thuan L. Thai available from O'Reilly & Associates, 1999.
When creating a COM object it is sometimes necessary to manage the object's lifetime. This prevents wasting system resources. This can be controlled by the reference count. Only the object knows when it should commit suicide, because all implementation details must be totally hidden from the outside world.
The question is when a reference count should be incremented and decremented. The COM specification stipulates a number of lifetime management rules that both the client and object must adhere to. These rules provide a consistent management of reference counts.
Notice that clients take part in determining an object's existence. Since a client is an outside entity, it should only see an interface pointer. With this interface pointer, a client can call AddRef and Release to increment and decrement an interface reference count, respectively. An object can implement reference counting anyway it chooses, but a client shouldn't care about this implementation detail.
So when do you call AddRef and when do you call Release? Here are some guidelines:
Existence Rules (for AddRef and Release)
A. Each time you make a copy of an interface pointer, you must AddRef the interface pointer.
B. When you no longer need an interface pointer, you must Release
C. If you have specific knowledge of an interface pointer's lifetime, you may cheat.
Here are some specific rules called out by the COM Specification:
- 1. If you make a copy of a global variable, you must AddRef. Call Release on the duplicated pointer when done using it.
- 2. For [in, out] interface pointer parameters, the caller and called function must follow these steps for consistency and predictability:
- a. The caller calls AddRef before invoking the method.
- b. The called function calls Release before overwriting the pointer.
- c. After overwriting, the called function calls AddRef for the pointer.
- d. The client is responsible for calling the Release on the received pointer.
- 3. A function such as QueryInterface, which magically brings a new interface pointer to life, must AddRef the synthesized pointer. This means that the caller must Release the returned interface pointer when the pointer is no longer needed.
- 4. When a called function returns a copy of an internal interface pointer, it must AddRef the interface pointer. The caller is responsible for calling Release.
You must always follow these four rules, in addition to A and B under Existence Rules. But you can cheat on rules A and B if you have definite knowledge regarding the birth and death of two or more copies of a given interface pointer. With this special intelligence, you can safely exclude certain AddRef and Release calls. Specifically there are two fairly safe cases in which you can cheat:
- 1. For [in] interface pointer parameters to subroutines, you don't need calls to AddRef and Release, because the lifetime of the duplicated pointer is nested within the larger scope.
- 2. For the duplicated interface pointers that are local variables, you may exclude the AddRef and Release calls. This is possible because the original interface pointer will survive until the end of the code block.
Other than these two cases, you'd better be very sure about the lifetime of the duplicated interface pointer before cheating. In other words, you can save a lot of headaches if you stick with just rules A and B.
This was first published in January 2000