保证一个类仅有一个实例,并提供一个访问它的全局访问点。
某个类只能有一个实例;
它必须自行创建这个实例;
它必须自行向整个系统提供这个实例。
用一个特殊方法来实例化所需的对象。
调用这个方法时,检查对象是否已经实例化。若已经实例化,该方法仅返回对该对象的一个引用。若未实力哈,该方法实例化该对象并返回对此新实例的一个引用。
为了确保这是实例化此类型对象的唯一方法,将这个类的构造函数定义为保护或者私有的。
构造函数私有化;
提供一个全局的静态方法(全局访问点)来获取单例对象;
在类中定义一个静态指针,指向本类的变量的静态变量指针。
class singleton { public: static singleton* getInstance() { if (instance == NULL) { instance = new singleton; } return instance; } private: /*不让类的外部再创建实例*/ singleton() { cout << "singleton" << endl; } private: /*指向本类唯一实例的指针*/ static singleton *instance; }; singleton* singleton::instance = NULL; int main(int argc, char **argv) { cout << "main" << endl; singleton *sig = singleton::getInstance(); return 0; }
当懒汉式遇见多线程时,需要利用加锁解锁机制,在对instance变量判断是否为空时之前加锁,防止多个线程同时判断是为空,返回2个new,违背了单例模式。
/*饿汉式-------在编译期间就已经确定该对象的唯一实例*/ class singleton { public: static singleton* getInstance() { return instance; } private: /*不让类的外部再创建实例*/ singleton() { cout << "singleton" << endl; } private: /*指向本类唯一实例的指针*/ static singleton *instance; }; singleton* singleton::instance = new singleton; int main(int argc, char **argv) { cout << "main" << endl; singleton *sig1 = singleton::getInstance(); singleton *sig2 = singleton::getInstance(); if (sig1 == sig2) { cout << "The same instance" << endl; } return 0; }
单例模式提供了对唯一实例的受控访问;
节约系统资源。只存在一个对象。
扩展略难。单例模式中没有抽象层;
单例类的职责过重。
系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器或者资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象;
客户调用类的单个实例只允许适用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。
打印机案例