#pragma once #include #include namespace fnd { template class SharedPtr { public: SharedPtr(); // constructor for creating owner object SharedPtr(T* ptr); // copy constructor SharedPtr(const SharedPtr& other); // destructor ~SharedPtr(); // own operator void operator=(T* ptr); // copy operator void operator=(const SharedPtr& other); // access ptr const T* operator*() const; T* operator*(); private: T* mPtr; size_t* mRefCnt; void deletePtr(); }; template inline SharedPtr::SharedPtr() : mPtr(nullptr), mRefCnt(new size_t) { *mRefCnt = 0; } template inline SharedPtr::SharedPtr(T* ptr) : SharedPtr() { *this = ptr; } template inline SharedPtr::SharedPtr(const SharedPtr& other) : SharedPtr() { *this = other; } template inline SharedPtr::~SharedPtr() { deletePtr(); } template inline void SharedPtr::operator=(T* ptr) { deletePtr(); if (ptr != nullptr) { mPtr = ptr; mRefCnt = new size_t; *mRefCnt = 1; } else { mPtr = nullptr; mRefCnt = new size_t; *mRefCnt = 0; } } template inline void SharedPtr::operator=(const SharedPtr& other) { deletePtr(); mPtr = other.mPtr; mRefCnt = other.mRefCnt; *mRefCnt += 1; } template inline const T* SharedPtr::operator*() const { return mPtr; } template inline T* SharedPtr::operator*() { return mPtr; } template inline void SharedPtr::deletePtr() { // if this is not the last reference if (*mRefCnt > 1) { // decrement reference count *mRefCnt -= 1; // make ptrs null mPtr = nullptr; mRefCnt = nullptr; } // if this is the last refeference else if (*mRefCnt == 1) { // delete memory delete mPtr; delete mRefCnt; // make ptrs null mPtr = nullptr; mRefCnt = nullptr; } // else if this is an empty refernce else if (*mRefCnt == 0) { delete mRefCnt; mPtr = nullptr; mRefCnt = nullptr; } } }