Smart Pointers and Reference Counting
Smart pointers are associated with a reference counter. The reference counter for an object keeps track of how many smart pointers reference the object. It is a data member of the object. The reference counter maintained by a smart pointer is automatically incremented each time a new smart pointer references an object. Similarly, it is decremented each time the number of smart pointers referencing that object decreases. An object is deleted when its reference counter returns to zero.
A given class A can support smart pointers if A publicly derives from the class . Derivation can be direct or transitive. IlsRefCounted includes a reference counter as a data member. It is the base class for and . This means that you can declare smart pointers to any classes deriving from IlsEntity or IlsObject. For details, see Server Objects and Defining Smart Pointers.
In case of multiple inheritance, we recommend that you make the derivation from IlsRefCounted virtual to avoid the very dangerous duplication of reference counters to an object.
Consider a class A that derives from both B and C, which in turn both derive from .
Deriving the Class IlsRefCounted
If B and C do not virtually derive from IlsRefCounted, A will contain two reference counters, one inherited from B and the other one inherited from C, as illustrated below.
Reference Counter
The value of one of the reference counters can drop to zero while the value of the other counter is still different from 0. As a consequence, A can be deleted although still pointed to. Making the derivation virtual avoids this type of problem.
Reference Cycles
A well-known problem associated with reference counters is that they generate floating reference cycles. A floating reference cycle is a phenomenon in which a set of objects point to each other in a circular way. Objects involved in such a cycle are never destroyed by the reference counting feature since they are always held by a smart pointer.
Floating Reference Cycle
Server avoids this trap by maintaining object-to-object relations that convey semantics. Relying on these relations, Server immediately and automatically breaks isolated reference cycles. If you use smart pointers instead of relations to point from one object to another, you should make sure that you do not create such reference cycles. Objects in a reference cycle are never destroyed and thus generate memory leaks.
Relations are explained in detail in Relations. See also Avoiding Floating Reference Cycles for information about the technique implemented by Server to avoid reference cycles and thus optimize the use of memory.