#include <iostream>
#include <vector>
class RefCounter
{
private:
int count = 0;
public:
void AddRef()
{
count++;
}
int Release()
{
return --count;
}
int getCount()
{
return count;
}
};
template<typename T> class sharedPTR
{
private:
T* myData;
RefCounter* myRef;
public:
sharedPTR() :
myData(0), myRef(0)
{
myRef = new RefCounter();
myRef->AddRef();
}
sharedPTR(T* pValue) :
myData(pValue), myRef(0)
{
myRef = new RefCounter();
myRef->AddRef();
}
~sharedPTR()
{
if (myRef && myRef->Release() == 0)
{
delete myData;
delete myRef;
}
}
sharedPTR(const sharedPTR<T>& ref) : myData(nullptr), myRef(nullptr)
{
if (ref.myRef && ref.myRef->getCount() < 3) {
myData = ref.myData;
myRef = ref.myRef;
myRef->AddRef();
}
}
sharedPTR<T>& operator = (const sharedPTR<T>& ref)
{
if (this == &ref) {
return *this;
}
if (myRef && myRef->Release() == 0)
{
delete myData;
delete myRef;
}
myData = nullptr;
myRef = nullptr;
if (ref.myRef && ref.myRef->getCount() < 3) {
myData = ref.myData;
myRef = ref.myRef;
myRef->AddRef();
}
return *this;
}
T& getData()
{
return *myData;
}
T* getPointer()
{
return myData;
}
};
class Cat
{
public:
Cat(unsigned int w_score, const std::string& w_name) :
score(w_score),
name(w_name)
{}
std::string getName()
{
return name;
}
unsigned int score;
private:
std::string name;
};
int main(void)
{
sharedPTR<Cat> newCat(new Cat(0, "Ferrari"));
// should print "Ferrari"
std::cout << newCat.getPointer()->getName() << std::endl;
// should also print "Ferrari"
std::cout << newCat.getData().getName() << std::endl;
newCat.getData().score = 50;
// should printf "50", as it was just assigned before
std::cout << newCat.getPointer()->score << std::endl;
// make some copies
sharedPTR<Cat> copyOfnewCat = newCat;
sharedPTR<Cat> copyOfnewCat2 = newCat;
// this copy should fail
sharedPTR<Cat> copyOfnewCat3 = newCat;
// should be nullptr
std::cout << copyOfnewCat3.getPointer() << std::endl;
// should be something other than 0 and equal
std::cout << "copy2 pointer: " << copyOfnewCat2.getPointer() << " copy1 pointer: " << copyOfnewCat.getPointer() << std::endl;
copyOfnewCat2.getData().score = 40;
// should be 40 now
std::cout << newCat.getPointer()->score << std::endl;
sharedPTR<Cat> copyOfnewCat4(newCat);
// should be nullptr
std::cout << copyOfnewCat4.getPointer() << std::endl;
}