我编写了一个非常简单的程序来实现一个通用的Singleton类,如下所示:
namespace core
{
template <typename T>
class Singleton
{
protected:
Singleton(void);
Singleton(Singleton const &other);
virtual ~Singleton(void);
public:
Singleton &operator=(Singleton const &other);
static T *GetSingletonPtr(void);
static T &GetSingleton(void);
static void DestroySingleton(void);
private:
static T *m_pInstance;
static T m_Instance;
};
//Globals initialization
template <typename T>
T *Singleton<T>::m_pInstance = NULL;
template <typename T>
T Singleton<T>::m_Instance = T();
//Initialization
template <typename T>
Singleton<T>::Singleton(void)
{
}
template <typename T>
Singleton<T>::Singleton(Singleton<T> const &other)
{
*this = other;
}
//Destruction
template <typename T>
Singleton<T>::~Singleton(void)
{
}
//Surcharges
template <typename T>
Singleton<T> &Singleton<T>::operator=(Singleton<T> const &other)
{
if (&other != this)
{
m_pInstance = other.m_pInstance;
m_Instance = other.m_Instance;
}
return (*this);
}
//Others
template <typename T>
T *Singleton<T>::GetSingletonPtr(void)
{
if (m_pInstance == NULL)
m_pInstance = new T();
return (m_pInstance);
}
template <typename T>
T &Singleton<T>::GetSingleton(void)
{
return (m_Instance);
}
template <typename T>
void Singleton<T>::DestroySingleton(void)
{
if (m_pInstance != NULL)
{
delete (m_pInstance);
m_pInstance = NULL;
}
}
}
然后,我在单例类'TestSingleton'的构造函数中使用日志'constructor:toto'编写了以下代码。
#include <iostream>
#include <Singleton.hpp>
class TestSingleton : public core::Singleton<TestSingleton>
{
friend class core::Singleton<TestSingleton>;
private:
TestSingleton(void)
{
std::cout << "constructor:toto" << std::endl;
}
};
class HandleSingleton
{
public:
void Handle()
{
TestSingleton &test = TestSingleton::GetSingleton();
}
};
int main(void)
{
getchar();
return (0);
}
输出如下:
$> constructor:toto
我不明白为什么即使初始化此引用的方法(此处为方法'Handle')未被调用,也会初始化带引用的变量?
提前感谢您的帮助!
答案 0 :(得分:3)
您的Singleton类使用T
的静态实例。在调用main
之前,将在程序启动期间初始化此实例。
粘贴中的以下代码初始化实例:
//Globals initialization
// […]
template <typename T>
T Singleton<T>::m_Instance = T();
答案 1 :(得分:0)
您的程序调用{{1}}实例的静态初始化和C ++标准版n3337 § 3.6.2 / 2说:
具有静态存储持续时间(3.7.1)或线程存储的变量 持续时间(3.7.2)应在任何其他之前进行零初始化(8.5) 初始化发生。
(...)
静态初始化应在任何动态初始化之前执行 发生(...)
答案 2 :(得分:0)
Normaly在实现Singleton类时使用成语“Construct On First Use”。
这个成语纠正了静态对象构造顺序上的一些问题(你可以搜索静态初始化顺序fiasco)。
将静态声明放在getObject方法上。然后在第一次调用此方法后调用构造函数。
Singleton的构造函数必须是私有的。
之后,根据定义,Singleton不可复制。你必须私有复制构造函数和operator =。