Singleton是全局变量的一种取代策略。
意图: 保证一个类仅有一个实例,并提供一个访问它的全局访问点。
实现:
Singleton.h:
class Singleton{
public:
static Singleton* Instance();
int TestFunc() {return 1;}
protected:
Singleton(){}; // 构造函数protected,可以防止外部代码创建Singleton实
例
private:
static Singleton* _instance;
};
Singleton.cpp:
#include "Singleton.h"
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance()
{
if (0 == _instance)
_instance = new Singleton;
return _instance;
}
通常在实际项目中,会用一个更通用的方法来代替每个单例中的重复代码,比如:
宏实现:
Singleton.h:
// 宏实现
#define DECLEAR_SINGLETON(class_name) \
static class_name* Instance() \
{ \
static class_name* _instance = 0; \
if (0 == _instance) \
_instance = new class_name; \
return _instance; \
}
class Singleton{
public:
DECLEAR_SINGLETON(Singleton)
int TestFunc(){return 1;}
protected:
Singleton(){}
};
Singleton.cpp里无须和单例有关的代码
上述实现的问题是 _instance是new出来的,但是无明确调用delete的地方,虽然程序退出后会回收该空间,但如果析构函数中有其它操作,则无法调用。修正如下:
#define DECLEAR_SINGLETON(class_name) \
static class_name* Instance() \
{ \
static class_name _instance; \
return &_instance; \
}
1. static 成员是在首次调用时创建的(因此这个单例模式满足惰性创建,即第一次使用时才创建);
2. 程序运行完后会调用static成员的析构函数并回收static成员的空间(因此程序结束时会调用析构函数);
3. 未考虑线程安全。
完整代码:
#define DECLEAR_SINGLETON(class_name) \
static class_name* Instance() \
{ \
static class_name _instance; \
return &_instance; \
}
class A{
public:
DECLEAR_SINGLETON(A)
~A() { printf ("decreate A\n");}
void test() {printf ("testtt\n");}
private:
A(){ printf ("create A\n");}
};
int main()
{
printf ("start test\n");
A::Instance()->test();
printf ("end test \n");
}
start test
create A
testtt
end test
decreate A