#include <iostream>
using namespace std;
template<class T>
class shr_ptr
{
T* resource;
int* count;
public:
shr_ptr():resource(NULL),count(NULL)
{
}
shr_ptr(T* res):resource(res)
{
count = new int(1);
}
shr_ptr(const shr_ptr<T>& R)
{
if(R.resource!=NULL)
{
resource = R.resource;
count = R.count;
*count = *R.count+1;
}
}
~shr_ptr()
{
if(resource!=NULL && --*(count)==0)
{
delete resource;
delete count;
resource = NULL;
}
}
shr_ptr<T>& operator = (const shr_ptr<T>& R)
{
if(R.resource != this->resource)
{
*count--;
resource = R.resource;
count = R.count;
*count++;
}
return *this;
}
T* operator ->() const
{
return resource;
}
T& operator * () const
{
return *resource;
}
T* get () const
{
return resource;
}
};
class A
{
public:
A()
{
cout << "created\n";
}
~A()
{
cout << "deleted\n";
}
};
int main()
{
shr_ptr<A> sh1 = new A;
shr_ptr<A> sh2 = new A;
sh1 = sh2;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGU8Y2xhc3MgVD4KY2xhc3Mgc2hyX3B0cgp7CiAgICAgICAgVCogcmVzb3VyY2U7CiAgICAgICAgaW50KiBjb3VudDsgCnB1YmxpYzoKICAgICAgICBzaHJfcHRyKCk6cmVzb3VyY2UoTlVMTCksY291bnQoTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgICAgICAKICAgICAgICB9IAoKICAgICAgICBzaHJfcHRyKFQqIHJlcyk6cmVzb3VyY2UocmVzKQogICAgICAgIHsKICAgICAgICAgICAgICAgIGNvdW50ID0gbmV3IGludCgxKTsKICAgICAgICB9IAoKICAgICAgICBzaHJfcHRyKGNvbnN0IHNocl9wdHI8VD4mIFIpCiAgICAgICAgewogICAgICAgICAgICAgICAgaWYoUi5yZXNvdXJjZSE9TlVMTCkKCQl7CgkJCXJlc291cmNlID0gUi5yZXNvdXJjZTsKCQkJY291bnQgPSBSLmNvdW50OwoJCQkqY291bnQgPSAqUi5jb3VudCsxOwoJCX0KICAgICAgICB9IAoKICAgICAgICB+c2hyX3B0cigpCiAgICAgICAgewogICAgICAgICAgICAgICAgaWYocmVzb3VyY2UhPU5VTEwgJiYgLS0qKGNvdW50KT09MCkKCQl7CgkJCWRlbGV0ZSByZXNvdXJjZTsKCQkJZGVsZXRlIGNvdW50OwoJCQlyZXNvdXJjZSA9IE5VTEw7CgkJfQogICAgICAgIH0KICAgICAgIAogICAgICAgc2hyX3B0cjxUPiYgb3BlcmF0b3IgPSAoY29uc3Qgc2hyX3B0cjxUPiYgUikKICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKFIucmVzb3VyY2UgIT0gdGhpcy0+cmVzb3VyY2UpCgkJewoJCQkqY291bnQtLTsKICAgICAgICAgICAgICAgICAgICAgICAgIHJlc291cmNlID0gUi5yZXNvdXJjZTsKICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ID0gUi5jb3VudDsKICAgICAgICAgICAgICAgICAgICAgICAgICpjb3VudCsrOwoJCX0KICAgICAgICAgICAgICAgIHJldHVybiAqdGhpczsKICAgICAgIH0KCiAgICAgICAgVCogb3BlcmF0b3IgLT4oKSBjb25zdCAKICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb3VyY2U7CiAgICAgICAgfQoKICAgICAgICBUJiBvcGVyYXRvciAqICgpIGNvbnN0IAogICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAqcmVzb3VyY2U7CiAgICAgICAgfQoKICAgICAgICBUKiBnZXQgKCkgY29uc3QgCiAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICAgIH0KfTsKCgoKY2xhc3MgQQp7CnB1YmxpYzoKCUEoKQoJewoJCWNvdXQgPDwgImNyZWF0ZWRcbiI7Cgl9Cgl+QSgpCgl7CgkJY291dCA8PCAiZGVsZXRlZFxuIjsKCX0KfTsKCmludCBtYWluKCkgCnsKCXNocl9wdHI8QT4gc2gxID0gbmV3IEE7CglzaHJfcHRyPEE+IHNoMiA9IG5ldyBBOwoJCglzaDEgPSBzaDI7CgkKCXJldHVybiAwOwp9