First commit
This commit is contained in:
commit
be5ecc883a
180
main.cpp
Normal file
180
main.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Simple shared pointer class with NO thread safety (not even the counter is thread-safe)
|
||||
*/
|
||||
template <typename T>
|
||||
class SharedPtr
|
||||
{
|
||||
//Rule 1: tracker is always NULL when ptr == NULL
|
||||
//Rule 2: ID is only assigned in constructors
|
||||
|
||||
typedef std::map<unsigned long,SharedPtr<T>*> IDMap;
|
||||
typedef std::pair<unsigned long,SharedPtr<T>*> 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<T>& 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 <typename T>
|
||||
unsigned long SharedPtr<T>::__IDCounter = 0;
|
||||
|
||||
template<typename T>
|
||||
SharedPtr<T>::SharedPtr(const SharedPtr &other)
|
||||
{
|
||||
this->tracker = other.tracker;
|
||||
this->ptr = other.ptr;
|
||||
this->ID = __IDCounter++;
|
||||
if(!isNull())
|
||||
tracker->insert(IDPair(ID,this));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
SharedPtr<T> &SharedPtr<T>::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<typename T>
|
||||
SharedPtr<T>::SharedPtr(T *new_ptr)
|
||||
{
|
||||
ptr = NULL;
|
||||
tracker = NULL;
|
||||
ID = __IDCounter++;
|
||||
reset(new_ptr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
SharedPtr<T>::~SharedPtr()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
unsigned long SharedPtr<T>::use_count() const
|
||||
{
|
||||
if(isNull())
|
||||
return 0;
|
||||
else
|
||||
return tracker->size();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
SharedPtr<T>::operator bool()
|
||||
{
|
||||
return !isNull();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T * const SharedPtr<T>::get()
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *SharedPtr<T>::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<typename T>
|
||||
void SharedPtr<T>::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<typename T>
|
||||
bool SharedPtr<T>::isNull()
|
||||
{
|
||||
return (ptr == NULL);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
SharedPtr<int> s;
|
||||
SharedPtr<int> x = SharedPtr<int>(new int(5));
|
||||
std::vector<SharedPtr<int> > myvec;
|
||||
for(long i = 0; i < 100; i++)
|
||||
{
|
||||
myvec.push_back(x);
|
||||
}
|
||||
SharedPtr<int> y(x);
|
||||
s = x;
|
||||
std::cout<<*x.get()<<std::endl;
|
||||
std::cout<<*y.get()<<std::endl;
|
||||
y.reset(NULL);
|
||||
|
||||
SharedPtr<int> R = SharedPtr<int>(new int(15));
|
||||
std::cout<<*R.get()<<std::endl;
|
||||
delete R.release();
|
||||
SharedPtr<int> T = SharedPtr<int>(new int(25));
|
||||
SharedPtr<int> U(T);
|
||||
std::cout<<*U.get()<<std::endl;
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user