单例模式是应用最多的一种设计模式,它要求每个类有且只能有一个实例对象,所以用C++设计一个单例模式的方法如下:
1 构造函数声明为私有; 这样就保证了不能随意构造一个对象
2 将拷贝构造函数与等号运算符声明为私有,并不提供他们的实现; 即禁止对象被拷贝。
3 在类中声明一个静态的全局访问接口;
4 声明一个静态的私有实例化指针;
- class Singleton
- {
- public:
-
- static Singleton *GetInstance()
- {
- if( instance_ == NULL )
- {
- instance_ = new Singleton;
- }
- return instance_;
- }
-
- ~Singleton()
- {
- cout << "~Singleton"<< endl;
- }
-
- private:
- Singleton(const Singleton& other);
- Singleton & operator=(const Singleton & other);
- Singleton()
- {
- cout << "Singleton"<<endl;
- }
-
-
- static Singleton *instance_;
- };
-
- Singleton * Singleton::instance_;
-
- int main(void)
- {
- Singleton *s1 = Singleton::GetInstance();
- Singleton *s2 = Singleton::GetInstance();
-
-
-
- return 0;
- }
上面就是单例类模式的C++实现,但是上述代码还有一个缺陷:
单例类中申请的一些资源没有被释放,如instance_指向的空间没有被回收
。一共有两种解决方式:
第一种解决方式:
- class Singleton
- {
- ...
-
- static void Free()
- {
- delete instance_;
- }
-
- ....
- };
-
- int main()
- {
- ...
- Singleton::Free();
- }
这种方式虽然能实现功能,但是不太方便,每次都要手动回收资源,这是它的缺点。
第二种解决方式:
- class Singleton
- {
- ...
- public:
- class Garbo
- {
- public:
- ~Garbo()
- {
- if( Singleton::instance_ != NULL )
- {
- delete instance_;
- }
- }
- };
-
- ...
- private:
- ...
- static Garbo garbo_;
- };
-
- Singleton::Garbo Singleton::garbo_;
这种方式提供的处理方式显然要比第一种方式来的要便捷,因为它依靠内部提供的Garbo嵌套类来提供服务,当Singleton类生命周期结束时,Garbo的类对象garbo_也要销毁,它将调用析构函数,而在析构函数中又自动地释放了Singleton单例类申请的一些资源,这种实现就比较智能化。不需要手动释放资源。这是它的优势。
下面提供另一种实现C++单例类模式的方法:
- class Singleton
- {
- public:
- static Singleton& GetInstance()
- {
- static Singleton instance_; return instance_;
- }
-
- ~Singleton()
- {
- cout << "~Singleton"<<endl;
- }
- private:
-
- Singleton()
- {
- cout << "Singleton "<<endl;
- }
- Singleton(const Singleton &other);
- Singleton & operator=(const Singleton &other);
- };
这种实现方式利用了static修改函数内部的变量,当第一次调用GetInstance函数时,系统将构造一个Singleton对象,在后续再次调用这个函数时,系统不再执行这个语句,也就不会再构造Singleton类对象了,而直接返回instance_本身。另外,当Singleton类对象生命周期结束时,对象会自动调用析构函数销毁,这里也就不存在申请资源之类的了,需要注意的是GetInstance()函数返回的是引用,这样就不会调用拷贝构造函数了,使用时也应该声明Singleton的引用,如下:
- int main()
- {
- Singleton &s1 = Singleton::GetInstance();
- Singleton &s2 = Singleton::GetInstance();
-
- return 0;
- }