#include <iostream>
#include <memory>
template<typename T>
struct Holder {
Holder() {
std::cout << "Holder()::Holder()" << std::endl;
if (!Self) Self = new T();
Self->Init();
}
~Holder() {
if (Self) {
Self->Cleanup();
delete Self;
std::cout << "~Holder()::Holder()" << std::endl;
}
}
T* Self = nullptr;
};
class SomeClass
{
public:
void Init(){}
void Cleanup() {}
int member;
};
////////////////////////////////////////////////////////////////////////////////////////
template <typename T>
class Singleton {
public:
static T* Instance() {
std::cout << "Singlton::Instance()" << std::endl;
static Holder<T> Dummy;
return Dummy.Self;
}
private:
Singleton() = delete;
Singleton(Singleton const&) = delete;
Singleton& operator= (Singleton const&) = delete;
Singleton(Singleton const&&) = delete;
Singleton& operator= (Singleton const&&) = delete;
};
int main()
{
{
auto pInst = Singleton<SomeClass>::Instance();
pInst->member = 10;
std::cout << pInst->member << std::endl;
std::unique_ptr<SomeClass> pObj(pInst);
}
auto pInst = Singleton<SomeClass>::Instance();
pInst->member = 20;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgoKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBIb2xkZXIgewogICBIb2xkZXIoKSB7CiAgICAgIHN0ZDo6Y291dCA8PCAiSG9sZGVyKCk6OkhvbGRlcigpIiA8PCBzdGQ6OmVuZGw7CiAgICAgIGlmICghU2VsZikgIFNlbGYgPSBuZXcgVCgpOwogICAgICBTZWxmLT5Jbml0KCk7CiAgIH0KICAgfkhvbGRlcigpIHsKICAgICAgaWYgKFNlbGYpIHsKICAgICAgICAgU2VsZi0+Q2xlYW51cCgpOwogICAgICAgICBkZWxldGUgU2VsZjsKICAgICAgICAgc3RkOjpjb3V0IDw8ICJ+SG9sZGVyKCk6OkhvbGRlcigpIiA8PCBzdGQ6OmVuZGw7CiAgICAgIH0KICAgfQogICBUKiBTZWxmID0gbnVsbHB0cjsKfTsKCmNsYXNzIFNvbWVDbGFzcwp7CnB1YmxpYzoKICAgdm9pZCBJbml0KCl7fQogICB2b2lkIENsZWFudXAoKSB7fQogICBpbnQgbWVtYmVyOwp9OwoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CmNsYXNzIFNpbmdsZXRvbiB7CnB1YmxpYzoKICAgc3RhdGljIFQqIEluc3RhbmNlKCkgewogICAgICBzdGQ6OmNvdXQgPDwgIlNpbmdsdG9uOjpJbnN0YW5jZSgpIiA8PCBzdGQ6OmVuZGw7CiAgICAgIHN0YXRpYyBIb2xkZXI8VD4gRHVtbXk7CiAgICAgIHJldHVybiBEdW1teS5TZWxmOwogICB9CnByaXZhdGU6CiAgIFNpbmdsZXRvbigpID0gZGVsZXRlOwogICBTaW5nbGV0b24oU2luZ2xldG9uIGNvbnN0JikgPSBkZWxldGU7CiAgIFNpbmdsZXRvbiYgb3BlcmF0b3I9IChTaW5nbGV0b24gY29uc3QmKSA9IGRlbGV0ZTsKICAgU2luZ2xldG9uKFNpbmdsZXRvbiBjb25zdCYmKSA9IGRlbGV0ZTsKICAgU2luZ2xldG9uJiBvcGVyYXRvcj0gKFNpbmdsZXRvbiBjb25zdCYmKSA9IGRlbGV0ZTsKfTsKCmludCBtYWluKCkKewogICB7CiAgICAgIGF1dG8gcEluc3QgPSBTaW5nbGV0b248U29tZUNsYXNzPjo6SW5zdGFuY2UoKTsKICAgICAgcEluc3QtPm1lbWJlciA9IDEwOwogICAgICBzdGQ6OmNvdXQgPDwgcEluc3QtPm1lbWJlciA8PCBzdGQ6OmVuZGw7CiAgICAgIHN0ZDo6dW5pcXVlX3B0cjxTb21lQ2xhc3M+IHBPYmoocEluc3QpOwogICB9CiAgIGF1dG8gcEluc3QgPSBTaW5nbGV0b248U29tZUNsYXNzPjo6SW5zdGFuY2UoKTsKICAgcEluc3QtPm1lbWJlciA9IDIwOwoKICAgcmV0dXJuIDA7Cn0K