在整个进程中,或者说是在整个工做过程当中,只容许有一个实例对象的存在 。这个实例对象可以完成所有工做过程所须要的属性和方法。因此不须要再有其余的实例!这个单例模式每每运用在某些资源受限的场景 中,和操做系统的 “互斥信号量” 很是类似。好比打印机,咱们限定只有一台打印机(资源受限),而后就得防止其余人另外开辟资源来实例化第二个打印机(能够理解为大家的资金只预算了这一台打印机,若是超预算,你得破产!)。而且这个资源不光是给一我的使用的,它是一个全局的访问点 !而且 一个类只能有这一个实例!ios
这个问题咱们分解成几个小的问题来看:c++
实例如何而来?在面向对象编程中,对象实例所有来自构造方法,因此只须要隐藏构造方法 ,让其余用户没法去自行实例化便可。那么这个实例就会是属于这个类的通常实例 。既然这个实例是属于类的,那么说明这个实例是一个静态成员 !程序员
只须要开放一个静态接口(由于实例也是静态的)。这个接口负责检查实例是否已经被建立,如若被建立就直接返回已经存在的实例,不然实例化一个给属于类的私有单例。编程
#include <iostream> using namespace std; class Singleton { private: static Singleton* MySingleInstance; Singleton() { cout << "单一实例已经被建立!" << endl; } public: static Singleton* GetMySingleInstance() { if (nullptr == MySingleInstance) MySingleInstance = new Singleton(); return MySingleInstance; } }; Singleton* Singleton::MySingleInstance = nullptr; int main() { Singleton* instance1 = Singleton::GetMySingleInstance(); Singleton* instance2 = Singleton::GetMySingleInstance(); if (instance1 == instance2) cout << "这是一个单例模式!" << endl; else cout << "这不是一个单例模式!" << endl; return 0; }
这是一种典型的《懒汉模式》的实现方式,由于这个单例,是在第一次使用到的时候才去初始化的!若是是《饿汉模式》,则是在尚未须要使用单例的时候就已经完成初始化了!其实要想实现《饿汉模式》很是简单,只须要把咱们的单例从一个对象指针变成一个静态的成员变量便可!以下:设计模式
#include <iostream> using namespace std; class Singleton { private: static Singleton MySingleInstance; Singleton() { cout << "单一实例已经被建立!" << endl; } public: static Singleton* GetMySingleInstance() { return &MySingleInstance; } }; Singleton Singleton::MySingleInstance;// 饿汉模式,这个类一存在这个单例就被建立! int main() { Singleton* instance1 = Singleton::GetMySingleInstance(); Singleton* instance2 = Singleton::GetMySingleInstance(); if (instance1 == instance2) cout << "这是一个单例模式(饿汉模式)!" << endl; else cout << "这不是一个单例模式!" << endl; return 0; }
《饿汉模式》实现的单例模式运行结果以下:安全
那么饿汉模式和懒汉模式在具体应用上有何区别呢?查阅资料得知有线程安全方面的问题,可是咱们这里只是初探,就不研究线程安全了!我我的理解来讲,线程安全应该相似于《操做系统》里面互斥型信号量在同步访问的时候的线程保护吧,我没有仔细研究,若有说错的地方,还请各位高手指出 !markdown
众所周知,懒汉模式下实现的单例,须要依赖动态内存分配。这种分配在堆空间的资源,必定是须要程序员经过代码来进行资源回收的!众所周知,只有尽可能完美作到RAII原则的c++程序员才是一个优秀的c++程序员!咱们该如何处理进程结束后的单例资源呢?框架
错误代码以下:ide
class Singleton { private: static Singleton* MySingleInstance; Singleton() { cout << "单一实例被建立!" << endl; } public: static Singleton* GetMySingleInstance() { if (nullptr == MySingleInstance) MySingleInstance = new Singleton(); return MySingleInstance; } ~Singleton() { delete Singleton::MySingleInstance; // delete 以后调用析构函数,而后析构函数又调用 delete … 循环往复! cout << "单例资源被释放" << endl; } }; Singleton* Singleton::MySingleInstance = nullptr;// 饿汉模式,这个类一存在这个单例就被建立! int main() { Singleton* instance = Singleton::GetMySingleInstance(); delete instance; return 0; }
这种操做没法完成析构,甚至还会陷入死循环带来程序崩溃 !缘由我在上面的注释里写到了:delete 以后调用析构函数,而后析构函数又调用 delete … 循环往复!函数
如何避免这个已经被delete后的对象,再次进入属于它的析构方法呢?只须要进行一次标记就好:
#include <iostream> using namespace std; class Singleton { private: static Singleton* MySingleInstance; Singleton() { cout << "单一实例被建立!" << endl; } public: static Singleton* GetMySingleInstance() { if (nullptr == MySingleInstance) MySingleInstance = new Singleton(); return MySingleInstance; } ~Singleton() { if (nullptr != MySingleInstance) {// 检测标记 Singleton::MySingleInstance = nullptr;// 作上标记 delete Singleton::MySingleInstance; } cout << "单例资源被释放" << endl; } }; Singleton* Singleton::MySingleInstance = nullptr;// 饿汉模式,这个类一存在这个单例就被建立! int main() { Singleton* instance = Singleton::GetMySingleInstance(); delete instance; return 0; }
众所周知,静态对象,在发生类建立的进程 结束后,会系统自动回收资源,这个资源的回收也是调用了静态对象的析构方法!因而咱们能够利用这个特色,让一个单例伴随一个静态对象,如何才能实现这点呢?只须要写一个内部类,建立一个内部类对象,这个对象是和成员属性、成员方法同级别的,是属于外部类的实例的!也就是属于单例的一个伴随对象!咱们只须要让这个对象成为一个静态对象,那么就能够在实例工做结束后,在它的析构中完成对实例的析构!
#include <iostream> using namespace std; class Singleton { private: static Singleton* MySingleInstance; Singleton() { cout << "单一实例被建立!" << endl; } class GarbageCollector { public: ~GarbageCollector() { if (nullptr != Singleton::MySingleInstance) { Singleton::MySingleInstance = nullptr;// 作上标记 delete Singleton::MySingleInstance; } cout << "单例资源被释放" << endl; } }; static GarbageCollector MyGC; public: static Singleton* GetMySingleInstance() { if (nullptr == MySingleInstance) MySingleInstance = new Singleton(); return MySingleInstance; } }; Singleton* Singleton::MySingleInstance = nullptr;// 饿汉模式,这个类一存在这个单例就被建立! Singleton::GarbageCollector Singleton::MyGC; int main() { Singleton* instance = Singleton::GetMySingleInstance(); return 0; }
假设须要对一个单例资源:打印机进行处于单例模式下的工做,个人代码以下:
#include <iostream> using namespace std; class printing { public: static printing* GetPrintingInstance() { if (nullptr == MyInstance) MyInstance = new printing(); return MyInstance; } class Garbo { public: ~Garbo(){ if (nullptr != printing::MyInstance) { printing::MyInstance = nullptr; delete printing::MyInstance; cout << "打印机实例注销" << endl; } } }; static Garbo MyGarbo; static int number; void doPrint() { cout << "打印机正在打印第:" << number << " 个打印任务" << endl; number++; } private: printing() { cout << "打印机实例启动" << endl; } static printing* MyInstance; }; int printing::number = 1; printing* printing::MyInstance = nullptr; printing::Garbo MyGarbo;// 默认构造,初始化 MyGarbo void doIt() { printing* util = printing::GetPrintingInstance(); int task = 20; while (task--) util->doPrint(); } int main() { doIt(); return 0; }
本人也没有在课堂上学过《设计模式》,也是在课余时间里作项目遇到了。深感设计模型、面向对象思想,在大型软件设计中的做用!他们都能大大提升代码的可复用性,减少工做量、减少代码冗余,增长软件的稳定性!因为没有正式学习设计模式,因而本文标题也只敢写:《初始设计模式》,写的不对或者很差的地方,还请各位前辈大佬提出,欢迎指正!!!!