#include <iostream>
template <typename T>
class shared_ptr {
T *ptr;
int *cnt;
public:
shared_ptr(T *ptr) : ptr(ptr), cnt(new int(1)) {}
shared_ptr(shared_ptr const& o) : ptr(o.ptr), cnt(o.cnt) { ++*cnt; }
~shared_ptr() { if (!--*cnt) { delete ptr; delete cnt; } }
friend inline void swap(shared_ptr& lhs, shared_ptr& rhs)
{ std::swap(lhs.ptr, rhs.ptr); std::swap(lhs.cnt, rhs.cnt); }
shared_ptr& operator=(shared_ptr rhs) { swap(*this, rhs); return *this; }
};
struct test {
const char *c;
test(const char *c):c(c){ std::cout << "construct " << c << '\n'; }
~test(){ std::cout << "destruct " << c << '\n'; }
};
int main()
{
shared_ptr<test> t(new test("A"));
{
shared_ptr<test> v(new test("B"));
{
shared_ptr<test> s(new test("C"));
shared_ptr<test> u(new test("D"));
t = s;
}
}
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CmNsYXNzIHNoYXJlZF9wdHIgewogIFQgKnB0cjsKICBpbnQgKmNudDsKcHVibGljOgogIHNoYXJlZF9wdHIoVCAqcHRyKSA6IHB0cihwdHIpLCBjbnQobmV3IGludCgxKSkge30KICBzaGFyZWRfcHRyKHNoYXJlZF9wdHIgY29uc3QmIG8pIDogcHRyKG8ucHRyKSwgY250KG8uY250KSB7ICsrKmNudDsgfQogIH5zaGFyZWRfcHRyKCkgeyBpZiAoIS0tKmNudCkgeyBkZWxldGUgcHRyOyBkZWxldGUgY250OyB9IH0KCiAgZnJpZW5kIGlubGluZSB2b2lkIHN3YXAoc2hhcmVkX3B0ciYgbGhzLCBzaGFyZWRfcHRyJiByaHMpCiAgeyBzdGQ6OnN3YXAobGhzLnB0ciwgcmhzLnB0cik7IHN0ZDo6c3dhcChsaHMuY250LCByaHMuY250KTsgfQogIHNoYXJlZF9wdHImIG9wZXJhdG9yPShzaGFyZWRfcHRyIHJocykgeyBzd2FwKCp0aGlzLCByaHMpOyByZXR1cm4gKnRoaXM7IH0KfTsKCnN0cnVjdCB0ZXN0IHsKICBjb25zdCBjaGFyICpjOwogIHRlc3QoY29uc3QgY2hhciAqYyk6YyhjKXsgc3RkOjpjb3V0IDw8ICJjb25zdHJ1Y3QgIiA8PCBjIDw8ICdcbic7IH0KICB+dGVzdCgpeyBzdGQ6OmNvdXQgPDwgImRlc3RydWN0ICIgPDwgYyA8PCAnXG4nOyB9Cn07CgppbnQgbWFpbigpCnsKICBzaGFyZWRfcHRyPHRlc3Q+IHQobmV3IHRlc3QoIkEiKSk7CiAgewogICAgc2hhcmVkX3B0cjx0ZXN0PiB2KG5ldyB0ZXN0KCJCIikpOwogICAgewogICAgICBzaGFyZWRfcHRyPHRlc3Q+IHMobmV3IHRlc3QoIkMiKSk7CiAgICAgIHNoYXJlZF9wdHI8dGVzdD4gdShuZXcgdGVzdCgiRCIpKTsKICAgICAgdCA9IHM7CiAgICB9CiAgfQp9Cg==