#include <iostream>
using namespace std;
template <typename T>
class s_ptr
{
public:
s_ptr<T>(T* ptr)
{
ref_count = new size_t(1);
this->ptr = ptr;
}
s_ptr<T>(const s_ptr<T>& rhs)
{
this->ref_count = rhs.ref_count;
this->ptr = rhs.ptr;
(*ref_count)++;
}
~s_ptr<T>()
{
cout << "Ref count: " << count() << endl;
if (ref_count && (*ref_count) == 1)
{
delete ref_count;
delete ptr;
return;
}
(*ref_count)--;
}
s_ptr<T>& operator=(const s_ptr<T>& rhs)
{
if (this != &rhs)
{
ptr = rhs.ptr;
ref_count = rhs.ref_count;
(*ref_count)++;
}
return this;
}
size_t count() const
{
return *ref_count;
}
private:
T* ptr = nullptr;
size_t* ref_count = nullptr;
};
class Base
{
public:
Base(){cout << "Base()\n";}
~Base(){cout << "~Base()\n";}
};
int main() {
// your code goes here
s_ptr<Base> b(new Base());
s_ptr<Base> bb = b;
s_ptr<Base> bbb(bb);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CmNsYXNzIHNfcHRyCnsKcHVibGljOgoJc19wdHI8VD4oVCogcHRyKQoJewoJCXJlZl9jb3VudCA9IG5ldyBzaXplX3QoMSk7CgkJdGhpcy0+cHRyID0gcHRyOwoJfQoJc19wdHI8VD4oY29uc3Qgc19wdHI8VD4mIHJocykKCXsKCQl0aGlzLT5yZWZfY291bnQgPSByaHMucmVmX2NvdW50OwoJCXRoaXMtPnB0ciA9IHJocy5wdHI7CgkJKCpyZWZfY291bnQpKys7Cgl9Cgl+c19wdHI8VD4oKQoJewoJCWNvdXQgPDwgIlJlZiBjb3VudDogIiA8PCBjb3VudCgpIDw8IGVuZGw7CgkJaWYgKHJlZl9jb3VudCAmJiAoKnJlZl9jb3VudCkgPT0gMSkKCQl7CgkJCWRlbGV0ZSByZWZfY291bnQ7CgkJCWRlbGV0ZSBwdHI7CgkJCXJldHVybjsKCQl9CgkJKCpyZWZfY291bnQpLS07Cgl9CgkKCXNfcHRyPFQ+JiBvcGVyYXRvcj0oY29uc3Qgc19wdHI8VD4mIHJocykKCXsKCQlpZiAodGhpcyAhPSAmcmhzKQoJCXsKCQkJcHRyID0gcmhzLnB0cjsKCQkJcmVmX2NvdW50ID0gcmhzLnJlZl9jb3VudDsKCQkJKCpyZWZfY291bnQpKys7CgkJfQoJCXJldHVybiB0aGlzOwoJfQoJCglzaXplX3QgY291bnQoKSBjb25zdAoJewoJCXJldHVybiAqcmVmX2NvdW50OwoJfQpwcml2YXRlOgoJVCogcHRyID0gbnVsbHB0cjsKCXNpemVfdCogcmVmX2NvdW50ID0gbnVsbHB0cjsKfTsKCmNsYXNzIEJhc2UKewpwdWJsaWM6CglCYXNlKCl7Y291dCA8PCAiQmFzZSgpXG4iO30KCX5CYXNlKCl7Y291dCA8PCAifkJhc2UoKVxuIjt9Cn07CgppbnQgbWFpbigpIHsKCS8vIHlvdXIgY29kZSBnb2VzIGhlcmUKCXNfcHRyPEJhc2U+IGIobmV3IEJhc2UoKSk7CglzX3B0cjxCYXNlPiBiYiA9IGI7CglzX3B0cjxCYXNlPiBiYmIoYmIpOwoJcmV0dXJuIDA7Cn0=