c++设计模式之单件模式

  C++中单件模式的意图是为了保证一个类 仅有一个实例,并提供一个访问它的全局访问点。
  动机: 对于一些类来说,只有一个实例是很重要的。虽然系统中可以有许多打印机,但却只应该有一个打印机假脱机,只应该有一个文件系统和一个窗口管理器。一个数据滤波器只能有一个A/D转换器。一个会计系统只能专用于一个公司。
  对于怎样才能保证一个类只有一个实例并且这个实例易于被访问?一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象,一个更好的办法是:让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建(通过截取创建对象的请求),并且它可以提供一个访问该实例的方法,这就是Singleton模式)。
  **适用性:**在下面的请款可以使用Singleton模式
     当类只能有一个实例而且客户可以从一个众所周知的访问点访问它;当这个唯一的实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

Singleton
static Instance()
SingletonOperation()
GetSingletonDate()
static uniqueInstance
singletonDate

  其中Instance()返回唯一的 return uniqueIstance
  参与者:

  •    Singleton :定义一个Instance操作,允许客户访问它的唯一实例。Instance是一个类操作(即Smalltalk中的一个类方法和C++中的一个静态成员函数);可能负责创建它自己的唯一实例。
      协作:
  • 客户只能通过Singleton的instance操作访问一个Singleton的实例。
      效果:
    模式有许多优点:
  • 1)对唯一实例的受控访问 : 因为Singleton类封装它的唯一实例,所以它可以严格的控制客户怎样以及何时访问它。
  • 2)缩小名空间 :Singleton模式是对全局变量的一种改进。它避免了那些存储唯一实例的全局变量污染名空间。
  • 3)允许对操作和表示的精化:Singleton类可以有子类,而且用这个扩展类的实例来配置一个应用是很容易的。你也可以用你所需要的类的实例在运行时刻配置使用。
  • 4)允许可变数目的实例:这个模式使得你易于改变你的想法,并允许Singleton类的多个实例。此外,你可以用相同的方法来控制应用所使用的实例的数目。只有允许访问Singleton实例的操作需要改变。
  • 比类操作更灵活:另一种封装单件功能的方式是使用类操作(既C++ 中静态成员函数或者是Smalltalk中的类方法)。但这两种语言技术都难以改变设计允许一个类有多个实例。此外,C++中的静态成员函数不是虚函数,因此子类不能多态的重定义它们。

  实现:
  下面是使用Singleton模式时所需要考虑的实现问题:

  • 1)保证一个唯一的实例:Singleton模式使得这个唯一实例是类的一般实例,但该类被写成只有一个实例能被创建。做到这一点的一个常用方法是将创建这个实例的操作隐藏在一个类操作(既:一个静态成员函数或者是一个类方法)后面,由它保证只有一个实例被创建。这个操作可以访问保存唯一实例的变量,而且它可以保证这个变量在返回值之前用这个唯一实例初始化。这种方法保证了单件在它的首次使用前被创建和使用。
      在C++中你可以用Singleton类静态成员函数Instance来定义这个类操作。Singleton还定义了一个静态成员变量_instance,它包含了一个指向它的唯一实例的直针。
//Singleton类定义如下:
class Singleton {
public:
	static Singleton* Instance();
protected:
	Singleton();
private:
	static Singleton* _instance;
};
//相应的实现是
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance() {
	if (_instance == 0) {
		_instance = new Singleton();
	}
	return _instance;
}

  客户仅通过Instance成员函数访问这个单件。变量_instance初始化为 0 ,而静态成员函数Instance返回该变量值,如果其值为 0 则用唯一实例初始化它。Instance 使用惰性(lazy)初始化;它的返回值直到被第一次访问时才创建和保存。
  注意构造器是保护型的(protected),试图直接实例化Singleton 的客户将得到一个编译时的错误信息。这就保证了仅有一个实例可以被创建。
  此外,因为_instance 是一个指向Singleton对象的指针,Instance 成员函数可以将一个纸箱Singleton 的子类的指针赋给这个变量。

你可能感兴趣的:(C++笔记)