#include #include #include /** * Simple shared pointer class with NO thread safety (not even the counter is thread-safe) */ template class SharedPtr { //Rule 1: tracker is always NULL when ptr == NULL //Rule 2: ID is only assigned in constructors typedef std::map*> IDMap; typedef std::pair*> IDPair; T* ptr; IDMap *tracker; //track pointers to same object unsigned long ID; static unsigned long __IDCounter; public: typedef T element_type; SharedPtr(const SharedPtr& other); SharedPtr& operator=(const SharedPtr& other); SharedPtr(T* new_ptr = NULL); ~SharedPtr(); unsigned long use_count() const; operator bool(); T* const get(); T* release(); void reset(T* new_ptr = NULL); inline bool isNull(); }; template unsigned long SharedPtr::__IDCounter = 0; template SharedPtr::SharedPtr(const SharedPtr &other) { this->tracker = other.tracker; this->ptr = other.ptr; this->ID = __IDCounter++; if(!isNull()) tracker->insert(IDPair(ID,this)); } template SharedPtr &SharedPtr::operator=(const SharedPtr &other) { this->tracker = other.tracker; this->ptr = other.ptr; this->ID = __IDCounter++; if(!isNull()) tracker->insert(IDPair(ID,this)); return *this; } template SharedPtr::SharedPtr(T *new_ptr) { ptr = NULL; tracker = NULL; ID = __IDCounter++; reset(new_ptr); } template SharedPtr::~SharedPtr() { reset(); } template unsigned long SharedPtr::use_count() const { if(isNull()) return 0; else return tracker->size(); } template SharedPtr::operator bool() { return !isNull(); } template T * const SharedPtr::get() { return ptr; } template T *SharedPtr::release() { T* ret_ptr = ptr; if(!isNull()) { IDMap* trackerHolder = tracker; for(typename IDMap::iterator it = trackerHolder->begin(); it != trackerHolder->end(); it++) { it->second->ptr = NULL; it->second->tracker = NULL; } delete trackerHolder; } return ret_ptr; } template void SharedPtr::reset(T *new_ptr) { if(!isNull()) { //ptr and tracker are not NULL, guaranteed if(tracker->size() == 1) //this is the last reference { delete ptr; ptr = NULL; delete tracker; tracker = NULL; } else { tracker->erase(ID); if(new_ptr != NULL) { tracker = new IDMap; tracker->insert(IDPair(ID,this)); } else { tracker = NULL; ptr = NULL; } } } else //if this is NULL { if(new_ptr != NULL) { if(tracker == NULL) { tracker = new IDMap; tracker->insert(IDPair(ID,this)); ptr = new_ptr; } } } } template bool SharedPtr::isNull() { return (ptr == NULL); } int main() { SharedPtr s; SharedPtr x = SharedPtr(new int(5)); std::vector > myvec; for(long i = 0; i < 100; i++) { myvec.push_back(x); } SharedPtr y(x); s = x; std::cout<<*x.get()< R = SharedPtr(new int(15)); std::cout<<*R.get()< T = SharedPtr(new int(25)); SharedPtr U(T); std::cout<<*U.get()<