As far as I can tell, rcgc_shared_ptr<T> calls the destructor of T as soon as its destructor is invoked, regardless of whether other references exist. That is, int main() { rcgc_shared_ptr<X> p1( new X ); { rcgc_shared_ptr<X> p2( p1 ); } // ~X is called here // *p1 references a destroyed object here } This doesn't seem correct to me; the point of shared_ptr is to not call the destructor of the pointee as long as references (such as p1 in the code above) exist to it. ------- Yes, you’re correct. The detor of rcgc_shared_ptr<X> calls the X’s detor As soon as rcgc_shared_ptr<X>’ object p2 leaves its scope. However P1 still holds the object. So only p2’s ~X() is called, not p1’s ~X(). If both called, the same object (new X()) will be free. Although calling dtors, but it does not mean certainly, free or mess-up the object generated by new X(). Only when the reference count decreased to zero, the object generated by new X() will be free. (Here I discussed with Andrey and Janson about if it’s valid to use the data which is called detor upon) So this is not the behavior you expected as shared_ptr you know. If you write X like this class X { public: std::string text; }; It can be a disaster as text object would be freed twice or more while the detor of X called maybe twice or more. but if you write X like this class X { public: rcgc_shared_ptrstd::string text; }; And use the text field accordingly, It will be good and correct, because rcgc_shared_ptr already managed the memory for you (including the situations that the detors of std::string Maybe called multiple times) I admit that I didn’t follow the semantics of the orginal shared_ptr. Maybe another name, just rcgc_ptr is better. It’s just smart pointer for you to manage memory allocations and deallocations. Maybe on the level of object creation/destructions is incorrect (with other way of managing pointers or objects), but rcgc_shared_ptr still cares it for you.