背景:MDI程序,点一个工具箱启动一个窗口,点几次,启动几个。
经典修改:判断是否为NULL,若为空则new。若在菜单栏也有工具箱,则
重复点工具箱的代码。若启动工具箱,把工具箱关闭,在点启动按钮,则工具箱窗口不见了。原因:关闭工具箱,实例没有NULL,而是disposed。可以在在判断条件加isdisposed的判断。若有五处修改的地方,则都要修改。
1.正确的做法;实例与否应该由工具箱自己判断。所有类的构造方法,你不提供,系统提供默认的,你提供了,默认无效。将工具箱类的构造方法写为Private,外部程序就不能new来实例化了。目的是类只能实例化一次,外部代码不能用new实例化,可以写一个Public的方法GetInstance(),该方法返回一个实例,做是否实例化过的判断。
单例模式(Singleton)
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
1.通常我们可以让一个全局变量使得一个对象被访问,但他不能防止你实例化多个对象。一个最好的方法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。
UML结构图
C++代码实现
class Singleton {
public:
//该方法是获得本类实例的唯一全局访问点
static Singleton* GetInstance()
{
//若实例不存在则new一个
if (m_sing == nullptr)
{
m_sing = new Singleton();
}
return m_sing;
}
private:
Singleton() {} //构造为私有,堵死了外界利用new实例的可能
static Singleton* m_sing;
};
Singleton* Singleton::m_sing = nullptr;
int main()
{
std::cout << "Hello World!\n";
Singleton* s1=Singleton::GetInstance();
Singleton* s2 = Singleton::GetInstance();
if (s1 == s2)
{
cout << "两个对象是同一个实例" << endl;
}
}
单例模式除了保证唯一的实例外,还有其他作用,比如单例模式因为Singleton类封装它的唯一实例,这样它可以严格控制客户怎样访问以及何时访问它。简单的说就是对唯一实例的受控访问。
3.多线程时的单例:多线程程序中,同时访问Singleton类,调用GetInstance()会有可能创建多个实例的。可以加锁。
不直接lock GetInstance()函数的原因,而是创建syncRoot来lock是因为加锁时,instance实例有没有被创建都不知道。
4.双重锁定
5.静态初始化