#include <iostream>
#include <memory>
class trigger
{
public:
trigger() : m_flag(true) {}
bool get() const { return m_flag; }
friend class trackable;
private:
void set(bool flag) { m_flag = flag; }
bool m_flag;
};
typedef std::shared_ptr<trigger> spy_type;
class trackable
{
public:
trackable(const trackable &)
: spy(std::make_shared<trigger>())
{}
trackable()
: spy(std::make_shared<trigger>())
{}
trackable &operator=(const trackable &) { return *this; }
~trackable() { spy->set(false); }
spy_type spy;
};
struct SomeObject : public trackable
{
//...
};
struct SomeClient
{
SomeObject * m_Object;
bool objectIsValid() const { return (spy) ? spy->get() : false; }
void setObject(SomeObject * obj)
{
m_Object = obj;
spy = obj->spy;
}
private:
spy_type spy;
};
int main()
{
SomeClient Client;
std::cout << std::boolalpha << Client.objectIsValid() << std::endl;
SomeObject * Object = new SomeObject();
Client.setObject(Object);
std::cout << Client.objectIsValid() << std::endl;
delete Object;
std::cout << Client.objectIsValid() << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgoKY2xhc3MgdHJpZ2dlcgp7CnB1YmxpYzoKICAgIHRyaWdnZXIoKSA6IG1fZmxhZyh0cnVlKSB7fQogICAgYm9vbCBnZXQoKSBjb25zdCB7IHJldHVybiBtX2ZsYWc7IH0KCiAgICBmcmllbmQgY2xhc3MgdHJhY2thYmxlOwoKcHJpdmF0ZToKICAgIHZvaWQgc2V0KGJvb2wgZmxhZykgeyBtX2ZsYWcgPSBmbGFnOyB9CiAgICBib29sIG1fZmxhZzsKfTsKCnR5cGVkZWYgc3RkOjpzaGFyZWRfcHRyPHRyaWdnZXI+IHNweV90eXBlOwoKY2xhc3MgdHJhY2thYmxlCnsKcHVibGljOgogICAgdHJhY2thYmxlKGNvbnN0IHRyYWNrYWJsZSAmKQogICAgICAgIDogc3B5KHN0ZDo6bWFrZV9zaGFyZWQ8dHJpZ2dlcj4oKSkKICAgIHt9CgogICAgdHJhY2thYmxlKCkKICAgICAgICA6IHNweShzdGQ6Om1ha2Vfc2hhcmVkPHRyaWdnZXI+KCkpCiAgICB7fQoKICAgIHRyYWNrYWJsZSAmb3BlcmF0b3I9KGNvbnN0IHRyYWNrYWJsZSAmKSB7IHJldHVybiAqdGhpczsgfQoKICAgIH50cmFja2FibGUoKSB7IHNweS0+c2V0KGZhbHNlKTsgfQogICAgc3B5X3R5cGUgc3B5Owp9OwoKCnN0cnVjdCBTb21lT2JqZWN0IDogcHVibGljIHRyYWNrYWJsZQp7CiAgICAvLy4uLgp9OwoKc3RydWN0IFNvbWVDbGllbnQKewogICAgU29tZU9iamVjdCAqIG1fT2JqZWN0OwoKICAgIGJvb2wgb2JqZWN0SXNWYWxpZCgpIGNvbnN0IHsgcmV0dXJuIChzcHkpID8gc3B5LT5nZXQoKSA6IGZhbHNlOyB9CgogICAgdm9pZCBzZXRPYmplY3QoU29tZU9iamVjdCAqIG9iaikKICAgIHsKICAgICAgICBtX09iamVjdCA9IG9iajsKICAgICAgICBzcHkgPSBvYmotPnNweTsKICAgIH0KCnByaXZhdGU6CiAgICBzcHlfdHlwZSBzcHk7Cn07CgoKaW50IG1haW4oKQp7CiAgICBTb21lQ2xpZW50IENsaWVudDsKCiAgICBzdGQ6OmNvdXQgPDwgc3RkOjpib29sYWxwaGEgPDwgQ2xpZW50Lm9iamVjdElzVmFsaWQoKSA8PCBzdGQ6OmVuZGw7CgogICAgU29tZU9iamVjdCAqIE9iamVjdCA9IG5ldyBTb21lT2JqZWN0KCk7CgogICAgQ2xpZW50LnNldE9iamVjdChPYmplY3QpOwoKICAgIHN0ZDo6Y291dCA8PCBDbGllbnQub2JqZWN0SXNWYWxpZCgpIDw8IHN0ZDo6ZW5kbDsKCiAgICBkZWxldGUgT2JqZWN0OwoKICAgIHN0ZDo6Y291dCA8PCBDbGllbnQub2JqZWN0SXNWYWxpZCgpIDw8IHN0ZDo6ZW5kbDsKCiAgICByZXR1cm4gMDsKfQ==