最近在Cpp的练习中使用了单例模式,在此总结一下。
以下文字部分来自:http://www.cnblogs.com/cxjchen/p/3148582.html
单例模式,可以说设计模式中最常应用的一种模式了,但是如果没有学过设计模式的人,可能不会想到要去应用单例模式,面对单例模式适用的情况,可能会优先考虑使用【全局或者静态变量】的方式,这样比较简单,也是没学过设计模式的人所能想到的最简单的方式了(这句话是血的教训啊,哈哈)。
一般情况下,我们建立的一些类是属于工具性质的,基本不用存储太多的跟自身有关的数据,在这种情况下,每次都去new一个对象,即增加了开销,也使得代码更加臃肿。其实,我们只需要一个实例对象就可以。如果采用全局或者静态变量的方式,会影响封装性,难以保证别的代码不会对全局变量造成影响。
考虑到这些需要,我们
“将默认的构造函数声明为私有的,这样就不会被外部所new了,甚至可以将析构函数也声明为私有的,这样就只有自己能够删除自己了。”
单例模式很容易实现:
1、直接就可以在静态区初始化instance,然后通过getInstance返回,这种就被称为饿汉式单例类。
2、在getInstance中new instance然后返回,这种就被称为懒汉式单例类,但这涉及到第一次getInstance的一个判断问题。
两者对比:
1.懒汉式是以时间换空间的方式。
2.饿汉式是以空间换时间的方式。
#include <iostream> #include <limits> #include <fstream> #include <string> using namespace std; class Screen { private: Screen() { }; ~Screen () { delete instance; } static Screen *instance; static int width; static int height; public: unsigned int getWidth(){ return width; } unsigned int getHeight(){ return height; } static Screen* getInstance(unsigned int width = 640, unsigned int height = 480) { if(instance == NULL)//懒汉式单例类 { instance = new Screen(); instance->width = width; instance->height = height; } return instance; } }; Screen* Screen::instance = 0; int Screen::width=0; int Screen::height=0;
以上的代码只能用于单线程模式,对于多线程模式,需要进行上锁
为了简单说明,此处用了一个C#的例子
Singleton* getInstance() { lock(); if (instance == NULL) { instance = new Singleton(); } unlock(); return instance; }
但这样写的话,会稍稍影响性能,因为每次判断是否为空都需要被锁定,如果有很多线程的话,就会造成大量线程的阻塞。于是大神们又想出了双重锁定。
Singleton* getInstance() { if (instance == NULL) { lock(); if (instance == NULL) { instance = new Singleton(); } unlock(); } return instance; }
但是,在《剑指offer》一书中,作者提出了更好的方案。
public sealed class Singleton4 { private Singleton4() { } public static void Print() { Console.WriteLine("Singleton4 Print"); } private static Singleton4 instance = new Singleton4();//饿汉式单例类 public static Singleton4 Instance { get { return instance; } } }
以及
public sealed class Singleton5 { Singleton5() { } public static void Print() { Console.WriteLine("Singleton5 Print"); } public static Singleton5 Instance { get { return Nested.instance; } } class Nested { static Nested() { } internal static readonly Singleton5 instance = new Singleton5(); } }
原文:http://www.cnblogs.com/wuqi/p/4668696.html