Update main.cpp

This commit is contained in:
Samer Afach 2017-04-06 11:35:02 +02:00
parent 3d46b8aac8
commit 17fb9c859b
1 changed files with 38 additions and 165 deletions

203
main.cpp
View File

@ -1,180 +1,53 @@
#include "SmartPtr.h"
#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);
SmartPtr<int> s;
SmartPtr<int> x = SmartPtr<int>(new int(5));
SmartPtr<int> y(x);
s = x;
std::cout<<*x.get()<<std::endl;
std::cout<<*y.get()<<std::endl;
std::cout<<*x<<std::endl;
std::cout<<*y<<std::endl;
y.reset(NULL);
SharedPtr<int> R = SharedPtr<int>(new int(15));
SmartPtr<int> R = SmartPtr<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);
SmartPtr<int> T = SmartPtr<int>(new int(25));
SmartPtr<int> U(T);
std::cout<<*U.get()<<std::endl;
std::vector<std::vector<std::string> > vec(1,std::vector<std::string>(10));
//vector
std::vector<SmartPtr<int> > myvec;
for(long i = 0; i < 10; i++)
{
myvec.push_back(SmartPtr<int>(new int(i)));
std::cout<<*myvec[i]<<"\t";
}
std::cout<<std::endl;
const std::vector<int*> myvec_raw = SmartPtr<int>::GetRawPtrContainer(myvec);
for(long i = 0; i < myvec_raw.size(); i++)
{
const int* const ptr = myvec_raw[i];
std::cout<<*ptr<<"\t";
}
std::cout<<std::endl;
int* ptr = new int(2);
int& i = *ptr;
std::cout<<i<<std::endl; //prints 2
ptr = new int(3);
std::cout<<*ptr<<std::endl; //prints 3
std::cout<<i<<std::endl; //still prints 2!
std::cout<<"End program"<<std::endl;
return 0;
}