设计模式C++实现(2)——单例模式
软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书,对于每个模式,用C++写了个小例子,加深一下理解。主要参考《大话设计模式》和《设计模式:可复用面向对象软件的基础》(DP)两本书。本文介绍单例模式的实现。
单例的一般实现比较简单,下面是代码和UML图。由于构造函数是私有的,因此无法通过构造函数实例化,唯一的方法就是通过调用静态函数GetInstance。
UML图:
代码:
- //Singleton.h
- class Singleton
- {
- public:
- static Singleton* GetInstance();
- private:
- Singleton() {}
- static Singleton *singleton;
- };
- //Singleton.cpp
- Singleton* Singleton::singleton = NULL;
- Singleton* Singleton::GetInstance()
- {
- if(singleton == NULL)
- singleton = new Singleton();
- return singleton;
- }
这里只有一个类,如何实现Singleton类的子类呢?也就说Singleton有很多子类,在一种应用中,只选择其中的一个。最容易就是在GetInstance函数中做判断,比如可以传递一个字符串,根据字符串的内容创建相应的子类实例。这也是DP书上的一种解法,书上给的代码不全。这里重新实现了一下,发现不是想象中的那么简单,最后实现的版本看上去很怪异。在VS2008下测试通过。
- //Singleton.h
- #pragma once
- #include <iostream>
- using namespace std;
- class Singleton
- {
- public:
- static Singleton* GetInstance(const char* name);
- virtual void Show() {}
- protected: //必须为保护,如果是私有属性,子类无法访问父类的构造函数
- Singleton() {}
- private:
- static Singleton *singleton; //唯一实例的指针
- };
- //Singleton.cpp
- #include "Singleton.h"
- #include "SingletonA.h"
- #include "SingletonB.h"
- 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;
- }
- //SingletonA.h
- #pragma once
- #include "Singleton.h"
- class SingletonA: public Singleton
- {
- friend class Singleton; //必须为友元类,否则父类无法访问子类的构造函数
- public:
- void Show() { cout<<"SingletonA"<<endl; }
- private: //为保护属性,这样外界无法通过构造函数进行实例化
- SingletonA() {}
- };
- //SingletonB.h
- #pragma once
- #include "Singleton.h"
- class SingletonB: public Singleton
- {
- friend class Singleton; //必须为友元类,否则父类无法访问子类的构造函数
- public:
- void Show(){ cout<<"SingletonB"<<endl; }
- private: //为保护属性,这样外界无法通过构造函数进行实例化
- SingletonB() {}
- };
- #include "Singleton.h"
- int main()
- {
- Singleton *st = Singleton::GetInstance("SingletonA");
- st->Show();
- return 0;
- }
上面代码有一个地方很诡异,父类为子类的友元,如果不是友元,函数GetInstance会报错,意思就是无法调用SingletonA和SIngletonB的构造函数。父类中调用子类的构造函数,我还是第一次碰到。当然了把SingletonA和SIngletonB的属性设为public,GetInstance函数就不会报错了,但是这样外界就可以定义这些类的对象,违反了单例模式。
看似奇怪,其实也容易解释。在父类中构建子类的对象,相当于是外界调用子类的构造函数,因此当子类构造函数的属性为私有或保护时,父类无法访问。为共有时,外界就可以访问子类的构造函数了,此时父类当然也能访问了。只不过为了保证单例模式,所以子类的构造函数不能为共有,但是又希望在父类中构造子类的对象,即需要调用子类的构造函数,这里没有办法才出此下策:将父类声明为子类的友元类。
本人享有博客文章的版权,转载请标明出处 http://blog.csdn.net/wuzhekai1985
设计模式C++实现(2)——单例模式相关推荐
- 一天一个设计模式(3)——单例模式
单例模式 单例模式是最简单也是最常用的一种设计模式了,通过单例模式,可以保证系统运行过程中,该类不会被重复实例化.即:一个类只有一个实例. 实现要求 单例类只能有一个实例. 单例类只能自己创建自己的实 ...
- Java并发程序设计(八)设计模式与并发之单例模式
设计模式与并发之单例模式 简单的单例实现: public class Singleton {private Singleton(){System.out.println("Creating ...
- 设计模式(一)单例模式:5-单元素枚举类模式
思想: 单元素的枚举类型已经成为实现 Singleton 的最佳方法. -- <Effective Java> 第三条:用私有构造器或者枚举类型强化 Singleton 属性 public ...
- 老王讲设计模式(三)——单例模式
单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例. 早晨,老王来到公司,发现小蔡正对着电脑屏幕发呆,于是走到小蔡身后,发现小 ...
- 创建型设计模式(1)—— 单例模式(Singleton Pattern)
文章目录 1.概述 2.简单实现 3.小结 参考文献 1.概述 使用设计模式可以提高代码的可复用性.可扩充性和可维护性.单例模式(Singleton Pattern),确保一个类只有一个实例,并提供一 ...
- 打通设计模式任督二脉 -- 单例模式
文章目录 1.设计模式介绍 2.单例模式 2.1.什么是单例模式? 2.2.单例模式实现方式 2.3.单例模式存在的问题 2.4.JDK源码中使用到的单例模式 前言:想必想了解设计模式的各位都是走开发 ...
- 设计模式学习2:单例模式
单例模式 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法). 比如Hibernate的SessionFa ...
- 23种设计模式(一)单例模式
2019独角兽企业重金招聘Python工程师标准>>> 定义 单例模式最初的定义出现于<设计模式>(艾迪生维斯理, 1994):"保证一个类仅有一个实例,并提供 ...
- 设计模式(一)-单例模式
1.单例模式[Singleton Pattern]: 设计模式:对问题行之有效的解决方式.其实它是一种思想,当人们在写代码的过程中,发现有些代码可提高效率,或者可复用,或者更灵活,在不断的实践中,提 ...
- 读秦小波《设计模式之禅》 -- 单例模式
新年第一天,在这里首先要祝大家新年快乐! 这篇文章中,介绍的是非常重要,也是非常常用的一种设计模式 -- 单例模式.例如,我们在电脑上登录QQ的时候,同一个QQ号码就只能登录一次,而不可能出现一个号码 ...
最新文章
- Hyper-V 3 虚拟机快照之四 导入/导出快照
- UVA10881蚂蚁
- python开发的模型部署_使用Python部署机器学习模型的10个实践经验
- 学用MVC4做网站五:5.1添加文章
- path.join 与 path.resolve 的区别
- 阿里开源软件替换指南
- 让IE浏览器提示下载或直接打开word文档
- 9.6分神作又出续集,这是成年人最不敢直视的现实
- linux Wi-Fi信号放大,wifi信号增强器
- python return的理解_python 浅析对return的理解
- iis7连接mysql_windows2008中正确使用IIS7配置PHP与MySQL
- Go 语言为Fibonacci函数实现Read方法
- 什么是随机存取_内存条的时序是什么?
- Unity web聊天通讯功能开发(1)
- markdown 设置目录跳转的简单方法
- LigerUI的简单使用示例
- 如何打开高清语音VOLTE
- 水卡修改金额_【技术分享】关于IC卡,水卡修改控制位教程
- 一个父亲对新婚女儿的自白
- Git 基本操作(入职亲体验)
热门文章
- adb需要安装java吗_jdk和adb配置及电脑装爽系统心得
- python自定义切片_自定义Python切片,请指教
- java 建立ssh隧道_SSH基础
- python中参数传递_python中参数传递
- 利用旧手机自建anki服务器,废旧手机变身服务器,打造私人云盘
- 【C语言进阶深度学习记录】九 C语言中const的详细分析
- 【C++深度剖析教程39】实现C++数组类模板
- 海康、大华IPC的rtsp格式
- 【转】Mybatis/Ibatis,数据库操作的返回值
- 职业生涯起步不要去顶级公司