博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++只允许实例化一次的类
阅读量:6982 次
发布时间:2019-06-27

本文共 2298 字,大约阅读时间需要 7 分钟。

1. 意图

  保证一个类仅有一个实例,并提供一个访问它的全局访问点。

2. 动机

  对一些类来说,只有一个实例是很重要的。虽然系统中可以有许多打印机,但却只应该有一个打印假脱机( printer spooler),只应该有一个文件系统和一个窗口管理器。一个数字滤波器只能有一个A / D转换器。一个会计系统只能专用于一个公司。

  我们怎么样才能保证一个类只有一个实例并且这个实例易于被访问呢?一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象。一个更好的办法是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建(通过截取创建新对象的请求),并且它可以提供一个访问该实例的方法。这就是Singleton模式。

3. 适用性

  在下面的情况下可以使用Singleton模式. 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

4. 结构

5. 参与者

  Singleton

  定义一个GetInstance操作,允许客户访问它的唯一实例。GetInstance是一个类操作(即Smalltalk中的一个类方法和C++中的一个静态成员函数)。可能负责创建它自己的唯一实例。

6. 协作

  客户只能通过Singleton的GetInstance操作访问一个Singleton的实例。

7. 效果

  Singleton模式有许多优点:

  1) 对唯一实例的受控访问因为Singleton类封装它的唯一实例,所以它可以严格的控制客户怎样以及何时访问它。

  2) 缩小名空间Singleton模式是对全局变量的一种改进。它避免了那些存储唯一实例的全局变量污染名空间。

  3) 允许对操作和表示的精化Singleton类可以有子类,而且用这个扩展类的实例来配置一个应用是很容易的。你可以用你所需要的类的实例在运行时刻配置应用。

  4) 允许可变数目的实例这个模式使得你易于改变你的想法,并允许Singleton类的多个实例。此外,你可以用相同的方法来控制应用所使用的实例的数目。只有允许访问Singleton实例的操作需要改变。

  5) 比类操作更灵活另一种封装单件功能的方式是使用类操作(即C++中的静态成员函数或者是Smalltalk中的类方法)。但这两种语言技术都难以改变设计以允许一个类有多个实例。

  此外,C++中的静态成员函数不是虚函数,因此子类不能多态的重定义它们。

8. 实现

class Singleton

{

  static std::auto_ptr<Singleton> m_pInstance;

protected:

  //prevent user making our any instance by manually

  //构造函数是保护类型的。

  Singleton(){}

public:

  ~Singleton(){}

  //Return this singleton class' instance pointer

  static Singleton* Instance()

  {

  if(!m_pInstance.get())

  {

  m_pInstance = std::auto_ptr<Singleton>(new Singleton());

  }

  return m_pInstance.get();

  }

 };


  怎样来使用它呢?不要试图从这个类派生你的单件子类,那样的结果是不妥当的,如果你需要多个单件子类,还是使用下面的宏定义更为妥当:

#define DEFINE_SINGLETON(cls)\

 private:\

  static std::auto_ptr<cls> m_pInstance;\

 protected:\

  cls(){}\

 public:\

  ~cls(){}\

  static cls* Instance(){\

  if(!m_pInstance.get()){\

  m_pInstance = std::auto_ptr<cls>(new cls());\

  }\

  return m_pInstance.get();\

 }

#define IMPLEMENT_SINGLETON(cls) \

std::auto_ptr<cls> cls::m_pInstance(NULL);


假定你需要实现一个单件类YY,这样书写:

class YY  

{

  DEFINE_SINGLETON(YY);

public:

  //your interfaces here...

};

在cpp文件中,书写:

IMPLEMENT_SINGLETON(YY);

需要引入这个类的实例的时候,使用这样的语句:

YY* pYY = YY::Instance();

这,就是全部。

如果需要定义其他的单件类,重复上面的定义,就可以了。

  当想集中管理一个应用程序所需的所有配置时,可以声明一个CToolsOptions的类,其中包含配置属性集合。对于这个类的实例,显然是一个实例就够了;当编写绘图程序时,考虑绘制矩形,圆形等分别使用CGraphTool派生的工具类,每个派生类负责处理具体的绘制动作和相关的UI相应逻辑。这些工具类典型的在被用户选择工具栏的图元按钮时被选中。依照这种模式,你应该对所有的图元工具从事注册工作,使得绘图程序了解运行时刻可以使用那些图元工具。同样的,负责管理注册信息的这个管理器也只需要一个实例就行了。

本文转自博客园知识天地的博客,原文链接:,如需转载请自行联系原博主。

你可能感兴趣的文章
PC如何接管手机的双因子身份验证 靠的是英特尔的CPU
查看>>
分析:“AI on Hadoop”有意义吗?
查看>>
起底英特尔大数据
查看>>
《中国人工智能学会通讯》——11.65 双重代价敏感的属性分类模型
查看>>
阿里云人工智能ET夺肺结节诊断世界冠军
查看>>
研究人员发现利用Excel宏可发起跳板攻击
查看>>
绿盟科技发布OpenSSL高危漏洞技术分析与防护方案 G20成员国美国、中国、德国受影响较大...
查看>>
《VMware Virtual SAN权威指南》一2.2.4 容量层设备
查看>>
物联网发展年报显示 2016年智能家居市场快速增长
查看>>
如何在React中做到jQuery-free
查看>>
4G+宽带高歌猛进:移动双线虐杀联通
查看>>
带你了解超大规模数据中心究竟有何不同?
查看>>
用Python实现每秒处理120万次HTTP请求
查看>>
Android单元测试 - 几个重要问题
查看>>
DNS服务器不能响应的四大解决办法
查看>>
美国税局再遭攻击:原是偷来的社会安全号码作祟
查看>>
如何在Kali Linux中安装Google Chrome浏览器
查看>>
勒索软件防不胜防? 要先从了解它开始
查看>>
大数据精准医疗解读遗传密码 未来医疗健康的变革
查看>>
神经网络基础:七种网络单元,四种层连接方式
查看>>