I just finished up writing a class to encapsulate a pointer-to-pointer that provides auto-release functionality like shared_ptr<T>.
I'm curious though, does something like this already exists, in the standard library, boost, ect?
I know the idea exists, because in the Unity Engine, when you call Destroy(gameObject), any and all references to that game object get set to null, which is what I want.
#pragma once
#include <stdlib.h>
template<class T>
class SafePtr
{
private:
class _sharedPtr
{
int ref_count;
T *ptr;
bool autorelease;
friend class SafePtr;
public:
_sharedPtr(T *p, bool autorelease) : ptr(p), ref_count(1), autorelease(autorelease)
{
}
virtual ~_sharedPtr()
{
if(autorelease) delete ptr;
}
void AddRef() { ++ref_count; }
int ReleaseRef() { return --ref_count; }
};
_sharedPtr *obj;
public:
SafePtr()
{
obj = new _sharedPtr(NULL, false);
}
// create a SafePtr to *p
explicit SafePtr(T *p, bool autorelease = true)
{
obj = new _sharedPtr(p, autorelease);
}
// link this to another instance of SafePtr
SafePtr(const SafePtr &sp)
{
// link this SafePtr to another SafePtr's data
obj = sp.obj;
obj->AddRef();
}
~SafePtr()
{
if(obj->ReleaseRef() == 0)
{
delete obj;
}
}
// set all instances of this SafePtr to *p
void set(T *p, bool autorelease = true)
{
if(obj->ptr != p)
{
// delete current object and assign new one
if(obj->autorelease)
delete obj->ptr;
obj->ptr = p;
obj->autorelease = autorelease;
// leave ref count intact
}
}
// link this to another instance of SafePtr
SafePtr &operator=(const SafePtr &p)
{
if(this != &p)
{
// release old pointer
if(obj->ReleaseRef() == 0)
{
delete obj;
}
// redirect to new data
obj = p.obj;
obj->AddRef();
}
return *this;
}
// set to NULL without deleting data
void Release()
{
if(obj->ReleaseRef() == 0)
{
delete obj;
}
obj = new _sharedPtr(NULL, false);
}
T &operator*() { return *obj->ptr; }
T *operator->() { return obj->ptr; }
operator T*() { return obj->ptr; }
operator bool() const { return obj->ptr != NULL; }
bool operator!() const { return obj->ptr == NULL; }
bool operator==(T *p) const { return obj->ptr == p; }
bool operator!=(T *p) const { return obj->ptr != p; }
bool operator==(const SafePtr &p) const { return obj == p.obj; }
bool operator!=(const SafePtr &p) const { return obj != p.obj; }
};