[设计模式] 5 单例模式 singleton
转处 http://blog.csdn.net/wuzhekai1985
软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书,对于每个模式,用C++写了个小例子,加深一下理解。主要参考《大话设计模式》和《设计模式:可复用面向对象软件的基础》(DP)两本书。本文介绍单例模式的实现。
单例的一般实现比较简单,下面是代码和UML图。由于构造函数是私有的,因此无法通过构造函数实例化,唯一的方法就是通过调用静态函数GetInstance。
UML图:
代码:
#include <iostream> using namespace std; class Singleton { public: static Singleton* GetInstance(); private: Singleton() {} static Singleton *singleton; }; Singleton* Singleton::singleton = NULL; Singleton* Singleton::GetInstance() { if(singleton == NULL) singleton = new Singleton(); return singleton; } int main() { Singleton* s = Singleton::GetInstance(); }
这里只有一个类,如何实现Singleton类的子类呢?也就说Singleton有很多子类,在一种应用中,只选择其中的一个。最容易就是在GetInstance函数中做判断,比如可以传递一个字符串,根据字符串的内容创建相应的子类实例。这也是DP书上的一种解法,书上给的代码不全。这里重新实现了一下,发现不是想象中的那么简单,最后实现的版本看上去很怪异。在VS2008下测试通过。
#include <iostream> #include <string.h> using namespace std; class Singleton { public: static Singleton* GetInstance(const char* name); virtual void Show() {cout << "Singleton" << endl;} protected: Singleton() {}// must be protectd, otherwise sub-class can't call father's ctor private: static Singleton *singleton; }; class SingletonA: public Singleton { friend class Singleton;//must be friend, otherwise father-class can't access sub-class's ctor public: void Show() { cout<<"SingletonA"<<endl; } private: SingletonA() {} //must be private, let outbound can't new a instance of SingltonA }; class SingletonB: public Singleton { friend class Singleton; //must be friend, otherwise father-class can't access sub-class's ctor public: void Show(){ cout<<"SingletonB"<<endl; } private: SingletonB() {} //must be private, let outbound can't new a instance of SingltonA }; Singleton* Singleton::singleton = NULL; Singleton* Singleton::GetInstance(const char* name) { if(singleton == NULL) { if(strcmp(name, "SingletonA") == 0) singleton = new SingletonA(); else if(strcmp(name,"SingletonB") == 0) singleton = new SingletonB(); else singleton = new Singleton(); } return singleton; } int main() { Singleton *st = Singleton::GetInstance("SingletonA"); st->Show(); return 0; }
上面代码有一个地方很诡异,父类为子类的友元,如果不是友元,函数GetInstance会报错,意思就是无法调用SingletonA和SIngletonB的构造函数。父类中调用子类的构造函数,我还是第一次碰到。当然了把SingletonA和SIngletonB的属性设为public,GetInstance函数就不会报错了,但是这样外界就可以定义这些类的对象,违反了单例模式。
看似奇怪,其实也容易解释。在父类中构建子类的对象,相当于是外界调用子类的构造函数,因此当子类构造函数的属性为私有或保护时,父类无法访问。为共有时,外界就可以访问子类的构造函数了,此时父类当然也能访问了。只不过为了保证单例模式,所以子类的构造函数不能为共有,但是又希望在父类中构造子类的对象,即需要调用子类的构造函数,这里没有办法才出此下策:将父类声明为子类的友元类。
相关文章
- 看透设计模式-结构型模式
- 设计模式——装饰模式
- JavaWeb_(设计模式)单例模式
- 设计模式之单例模式的多种使用方式以及单例的优化
- 设计模式之单例模式的多种使用方式
- <<.NET B/S 架构实践>> 几种概念区别 - 算法、设计模式、企业应用架构模式、架构模式
- 炒冷饭系列:设计模式 单例模式
- 设计模式——单例模式
- iOS设计模式之单例模式
- 设计模式(5)-己所不欲,施之于人(代理模式)
- C#设计模式——观察者模式(Observer Pattern)1
- 【设计模式】桥接模式
- 【设计模式】建造者模式
- 不一样的策略模式(设计模式五)
- 「补课」进行时:设计模式(18)——访问者模式
- 设计模式复习--单例模式
- 《设计模式之禅》--单例扩展:多例模式
- 【java设计模式】之 建造者(Builder)模式
- 不一样的适配器模式(设计模式三)
- Java设计模式之《观察者模式》及应用场景
- 【项目实战】设计模式之单例模式
- 大话设计模式(四)单例模式
- python 设计模式之单例模式 Singleton Pattern
- python 设计模式之享元(Flyweight)模式
- 设计模式学习总结(三)——单例模式
- Java 设计模式:实战访问者模式「模拟家长与校长,对学生和老师的不同视角信息的访问场景」
- 设计模式(Python语言)----桥模式
- 设计模式----代理模式
- 23种类设计模式--1单例模式