0

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; }
};

Edited by VBNick: n/a

1
Contributor
1
Reply
2
Views
5 Years
Discussion Span
Last Post by VBNick
This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.