#include <iostream>
#include <memory>
template<typename T>
class CountedInstance
{
public:
CountedInstance() { sCount++; }
~CountedInstance() { --sCount; }
unsigned count() const { return sCount; }
private:
static unsigned sCount;
};
template<typename T>
unsigned CountedInstance<T>::sCount = 0;
template<class T>
class SharedResource : public CountedInstance<T>
{
public:
typedef std::shared_ptr<T> Ptr;
SharedResource() : mPtr((this->count() == 1) ? Ptr(new T) : Ptr()) {}
private:
Ptr mPtr;
};
struct Timer {
Timer() { std::cout << "Create Timer" << std::endl; }
~Timer() { std::cout << "Destroy Timer" << std::endl; }
};
struct Widget : public SharedResource<Timer>
{
Widget() { std::cout << " Create Widget " << this->count() << std::endl; }
~Widget() { std::cout << " Destroy Widget " << this->count() << std::endl; }
};
int main()
{
{ Widget w1, w2, w3; }
{ Widget w1, w2, w3; }
{ Widget w1, w2, w3; }
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgoKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CmNsYXNzIENvdW50ZWRJbnN0YW5jZQp7CnB1YmxpYzoKICAgIENvdW50ZWRJbnN0YW5jZSgpIHsgc0NvdW50Kys7IH0KCiAgICB+Q291bnRlZEluc3RhbmNlKCkgeyAtLXNDb3VudDsgfQoKICAgIHVuc2lnbmVkIGNvdW50KCkgY29uc3QgeyByZXR1cm4gc0NvdW50OyB9Cgpwcml2YXRlOgogICAgc3RhdGljIHVuc2lnbmVkIHNDb3VudDsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnVuc2lnbmVkIENvdW50ZWRJbnN0YW5jZTxUPjo6c0NvdW50ID0gMDsKCgp0ZW1wbGF0ZTxjbGFzcyBUPgpjbGFzcyBTaGFyZWRSZXNvdXJjZSA6IHB1YmxpYyBDb3VudGVkSW5zdGFuY2U8VD4KewpwdWJsaWM6CiAgICB0eXBlZGVmIHN0ZDo6c2hhcmVkX3B0cjxUPiBQdHI7CgogICAgU2hhcmVkUmVzb3VyY2UoKSA6IG1QdHIoKHRoaXMtPmNvdW50KCkgPT0gMSkgPyBQdHIobmV3IFQpIDogUHRyKCkpIHt9Cgpwcml2YXRlOgogICAgUHRyIG1QdHI7Cn07CgoKc3RydWN0IFRpbWVyIHsKICAgIFRpbWVyKCkgeyBzdGQ6OmNvdXQgPDwgIkNyZWF0ZSBUaW1lciIgPDwgc3RkOjplbmRsOyB9CiAgICB+VGltZXIoKSB7IHN0ZDo6Y291dCA8PCAiRGVzdHJveSBUaW1lciIgPDwgc3RkOjplbmRsOyB9Cn07CgpzdHJ1Y3QgV2lkZ2V0IDogcHVibGljIFNoYXJlZFJlc291cmNlPFRpbWVyPgp7CiAgICBXaWRnZXQoKSB7IHN0ZDo6Y291dCA8PCAiICBDcmVhdGUgV2lkZ2V0ICIgPDwgdGhpcy0+Y291bnQoKSA8PCBzdGQ6OmVuZGw7IH0KICAgIH5XaWRnZXQoKSB7IHN0ZDo6Y291dCA8PCAiICBEZXN0cm95IFdpZGdldCAiIDw8IHRoaXMtPmNvdW50KCkgPDwgc3RkOjplbmRsOyB9Cn07CgppbnQgbWFpbigpCnsKICAgIHsgV2lkZ2V0IHcxLCB3MiwgdzM7IH0KICAgIHsgV2lkZ2V0IHcxLCB3MiwgdzM7IH0KICAgIHsgV2lkZ2V0IHcxLCB3MiwgdzM7IH0KfQ==