Listing 2

template <class T> class ReferenceCountedPointer {
    T* pointer;

    // Throw away our reference and delete object if this was the last one.
    void zeroPointer() {
        if (pointer != NULL) {
            if (pointer->count > 0) pointer->count -= 1;
            if (pointer->count <= 0) delete pointer;
            pointer = NULL;
        }
    }

    void setPointer(T* x) {
        if (x != pointer) {
            // Decrement the count for the old object before reassigning
            zeroPointer();
            if (x != NULL) {
                // Increment the count for the new object
                pointer = x;
                pointer->ReferenceCountedObject_refCount += 1;
            }
        }
    }

public:
    // Allow *ptr, ptr->method(), and ptr->member to work as if ptr was a T*
    inline T& operator*() const { return (*pointer); }
    inline T* operator->() const { return pointer; }
    
    // This pointer is going out of scope, so decrement the count
    inline ~ReferenceCountedPointer() { zeroPointer(); }

    // Pointer assignment. Allow subtyping rule RCP<T> <: RCP<S> if T<: S
    template <class S>
    inline ReferenceCountedPointer<T>& operator=
        (const ReferenceCountedPointer<S>& p) : pointer(NULL) {
        setPointer(p.getPointer());
        return *this;
    }
};