con*_*ref 3 c++ singleton templates
以下代码是我对Singleton Pattern的实现.
#include <iostream>
template<class T>
class Uncopyable
{
protected:
Uncopyable(){}
~Uncopyable(){}
private:
Uncopyable(const Uncopyable<T>&);
Uncopyable& operator=(const Uncopyable<T>&);
};
template <class T>
class Singleton : private Uncopyable<T>
{
public:
static T* getInstancePtr()
{
return instance;
}
protected:
Singleton<T>()
{
if(instance == 0)
{
instance = new T();
}
};
~Singleton<T>()
{
};
private:
static T* instance;
};
template<class T> T* Singleton<T>::instance = 0;
class Test : public Singleton<Test>
{
public:
Test(){};
~Test(){};
inline void test() const
{
std::cout << "Blah" << std::endl;
}
private:
friend class Singleton<Test>;
protected:
};
int main(int argc, char* argv[])
{
Test* t = Test::getInstancePtr();
Test* t2 = Test::getInstancePtr();
t->test();
t2->test();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它以这种形式工作,但我不确定它是否真的是正确的,因为Singleton的构造函数和析构函数受到保护而不是私有.如果我将它们声明为私有,则代码将无法编译,因为类无法访问它们.这个实现是否可以安全使用,或者我可以做些什么来改进它以确保只创建和使用一个实例.
谢谢
这肯定是单身人士的错误实施.该实现存在太多问题.
在C++ 11中,您可以使用std::call_once
和std::once_flag
实现单例模式.这是一个例子:
//CRTP base singleton class
template<typename TDerived>
class Singleton
{
static std::unique_ptr<TDerived> m_instance;
static std::once_flag m_once;
protected:
Singleton() {}
public:
~Singleton() { }
static TDerived & GetInstance()
{
std::call_once
(
Singleton::m_once,
[] (){ Singleton::m_instance.reset( new TDerived() ); }
);
return *m_instance;
}
};
template<typename TDerived>
std::unique_ptr<TDerived> Singleton<TDerived>::m_instance;
template<typename TDerived>
std::once_flag Singleton<TDerived>::m_once;
Run Code Online (Sandbox Code Playgroud)
现在你可以从中得到:
class Demo : public Singleton<Demo>
{
public:
void HelloWorld() { std::cout << "HelloWorld" << std::endl; }
};
//call HelloWorld() function through singleton instance!
DemoSingleton::GetInstance().HelloWorld();
Run Code Online (Sandbox Code Playgroud)