搞笑解释:
俺有6个漂亮的老婆,她们的老公都是我,我就是我们家里的老公Sigleton,她们只要说道“老公”,都是指的同一个人,那就是我
定义:
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用。
人话:
保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。(你就是个全局变量的程度啊)
于是,可以写出以下的事例:
class Singleton { public: static Singleton* Object(){ //公有的静态方法,来获取该实例 if (pIn == NULL) pIn = new Singleton(); return pIn; } private: Singleton(){}; //私有构造函数,防止实例化 static Singleton* pIn; //私有静态指针变量,指向类的唯一实例 };
接下来我们可以测试一下这个类是否只有一个实例。
Singleton* Singleton::pIn = NULL; // 这一行必须声明,不然编译不通过,原因可以参考我的博客<static成员> int main() { Singleton* pS1 = Singleton::Object(); Singleton* pS2 = Singleton::Object(); Singleton* pS3 = pS1->Object(); Singleton &pS4 = * Singleton::Object(); if (pS1 == pS2) cout << "pS1 == pS2" << endl; if (pS1 == pS3) cout << "pS1 == pS3" << endl; if (pS1 == &pS4) cout << "pS1 == &pS4" << endl; system("pause"); }
结果输出:
pS1 == pS2 pS1 == pS3 pS1 == &pS4
可以得知:得到的全是一个实例!
另外,从测试函数中我们可以发现单例类有以下的性质:
1.它有一个指向唯一实例的静态指针pIn,并且是私有的;
2.它有一个公有的函数,可以获取这个唯一的实例,并且在需要的时候创建该实例;
3.它的构造函数是私有的,这样就不能从别处创建该类的实例。
上面的单例类中,我们new了一个实例,但是却没有释放它,可能你想会有这么几种方法来解决:
1.在程序结束时调用 GetInstance(),并对返回的指针掉用 delete操作。这样做可以实现功能,但不仅很丑陋,而且容易出错。因为这样的附加代码很容易被忘记,而且也很难保证在delete之后,没有代码再调用 GetInstance 函数。也就是说释放操作由使用者来管理,而不是由类本身来管理,这违背了类的单一职责的原则,这是不合理的。
2.用析构函数?
很遗憾,就算我们声明了析构函数,还是不能释放,因为我们的实例是new出来的,所以只有 delete 时,才会调用析构函数,但是在哪里调用 delete 呢!
3.用静态局部变量来解决:
class Singleton { public: static Singleton* Object(){ static Singleton pIn; //静态局部变量 return &pIn; } private: Singleton(){}; };
局部静态对象实例 instance 是第一次调用 GetInstance() 时被构造,一直保持活动状态直到应用程序终止.
与动态分配对象不同,静态对象当应用程序终止时被自动销毁掉,所以就不必再手动销毁实例了。