Reference Count Implementation

Reference counted objects must be allocated on the heap via operator new. In order to enforce this, all reference counted classes have a protected destructor. A reference counted object is created with a reference count of 1 and a floating flag set to true. calls to ref() will increment the reference count, calls to unref() will decrement the reference count. Additionally, there is a function ref_sink() to "consume" the floating state, it essentially does:

void
ref_sink()
{
  ref();
  if (floating)
  {
    floating = false;
      unref();
  }
}

In unref(), if the reference count drops to 0, the object will be destroyed via the delete operator. A warning may be issued if the object is still floating at this point, depending on whether the project policy allows unref (new Ref-Countable) semantics without ever sinking the object. ref() should refuse to operate on objects with a ref_count < 1 to catch after-delete reference counting operations where possible.

Threading Considerations

The reference counting primitives can be made atomic or thread-safe in terms of compare-and-swap with code like:

ref():          do tmp = ref_count;
                while (!compare_and_swap(&ref_count, tmp, tmp + 1));
unref():        do tmp = ref_count;
                while (!compare_and_swap(&ref_count, tmp, tmp - 1));
                if (tmp == 1) /* destruction follows */;
ref_sink():     ref(); /* ref_count now >= 1 + (floating != false) */
                do tmp = ref_count;
                while ((tmp & FLOATING_BIT) &&
                       !compare_and_swap(&ref_count, tmp, tmp - (FLOATING_BIT + 1)));
                /* ref_count now >= 1 */

It is desirable to use a very high bit for FLOATING_BIT, like 2147483648 to avoid early overflow in the above logic.