c\c++复习基础要点08--c++单例模式
单例模式有许多种实现方法,在c++中,甚至可以直接用一个全局变量做到这一点,但是这样的代码显得不优雅。使用全局对象能够保证方便地访问实例,但是不能保证只声明一个对象——也就是说除了一个全局实例外,仍然能创建相同类的本地实例。
定义一个单例类,使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态函数获取该实例。
定义:
class CSingleton
{
public:
staticCSingleton * GetInstance()
{
if(m_pInstance==NULL)
m_pInstance = new CSingleton();
return m_pInstance;
}
private:
CSingleton(){};
staticCSingleton * m_pInstance;
};
用户访问唯一实例的函数只有GetInstance()成员函数。因为类的构造函数是私有的。GetInstance()的返回值是当这个函数第一次被调用时创建的实例。所以GetInstance()之后调用都返回同一个实例的指针。
单例类CSingleton的特征:
1. CSingleton有一个指向唯一实例的静态指针m_pInstance,并且是私有的;
2. CSingleton有一个公有的函数,可以获得这个唯一的实例,并且在需要的时候创建实例;
3. CSingleton的构造函数是私有的,这样就不能从别处创建该类的实例。
但是该种实现单例类的方法有一个问题:m_pInstance指向的空间(实例)什么时候释放?
该实例的析构函数什么时候执行?
解决办法:让这个类自己知道在合适的时候把自己释放,或者把释放自己的操作让操作系统在某个适合时候执行。
在程序结束时,系统会自动析构所有的全局变量。事实上,系统也会析构该类的所有静态成员变量。利用这个特征,可以在单例类中定义一个内嵌类的静态成员变量,而这个内嵌类的唯一工作就是在析构函数中去释放单例类的实例。
在CSingleton类中定义一个CGarbo类的静态成员变量:
class CSingleton
{
public:
static CSingleton * GetInstnace()
{
if(m_pInstance==NULL)
m_pInstance = newCSingleton();
return m_pInstance;
}
private:
CSingleton();
static CSingleton * m_pInstance;
class CGarbo
{
public:
~CGarbo()
{
if(CSingleton::m_pInstance)
delete CSingleton::m_pInstance;
}
};
static CGarbo Garbo;
};
类CGarbo被定义为CSingleton的私有内嵌类,以防该类被在其他地方滥用。
程序运行结束时,系统会调用CSingleton的静态成员Garbo的析构函数,该析构函数会删除单例的唯一实例。
使用这种方法释放单例对象有以下特征:
在单例类内部定义专有的嵌套类;
在单例类内定义私有的专门用于释放的静态成员;
利用程序在结束时析构全局变量的特性,选择最终的释放时机;
使用单例的代码不需要任何操作,不必关心对象的释放。
另一种实现单例类的方法:定义单例类的实例为GetInstance函数的局部静态变量。
class CSingleton
{
public:
static CSingleton &GetInstance()
{
static CSingleton instance;
return instance;
}
private:
CSingleton(){};
};
使用局部静态变量,非常强大的方法,完全实现了单例的特性,而且代码量更少,也不用担心单例销毁的问题。
但使用此种方法也会出现问题,当如下方法使用单例时问题来了,
Singletonsingleton = Singleton :: GetInstance();
这么做就出现了一个类拷贝的问题,这就违背了单例的特性。产生这个问题原因在于:编译器会为类生成一个默认的构造函数,来支持类的拷贝。
解决方法:禁止类拷贝和类赋值,禁止程序员用这种方式来使用单例
class CSingleton
{
public:
static CSingleton &GetInstance()
{
static CSingleton instance;
return instance;
}
private:
CSingleton(){};
CSingleton(const CSingleton &){};
CSingleton & operate=(constCSingleton &){};
};
关于CSingleton(const Singleton&); 和 CSingleton & operate = (const Singleton&); 函数,需要声明成私用的,并且只声明不实现。这样就可以解决上边的问题,实现单例类。
c\c++复习基础要点08--c++单例模式的更多相关文章
- c/c++ 复习基础要点01-const指针、指针函数 函数指针、new/delete与malloc/free区别与联系
1. 引用本身是有指针实现的:引用为只读指针 例子: int d=123; int& e=d; //引用 int * const e=d; //只读指针,e指向d,不可修改e指 ...
- c++复习基础要点02 虚函数与模板 与static inline是否共存
1. 虚函数能否定义为模板函数 当一个类有虚函数时,它一定有一个虚表,用来纪录每个虚函数的实际地址.这也就是说这个虚表的大小是在编译期就确定了的.有多少个虚函数,虚表就纪录几个. ...
- c\c++复习基础要点16----枚举类型
枚举类型: 语法格式: enum 枚举类型名 {变量值列表}; 例如: enum Weekday{sun, mon, tue, wed, thu, fri, set}; 声明了枚举类型后,就可以定义 ...
- iOS系列 基础篇 08 文本与键盘
iOS系列 基础篇 08 文本与键盘 目录: 1. 扯扯犊子 2. TextField 3. TextView 4. 键盘的打开和关闭 5. 打开/关闭键盘的通知 6. 键盘的种类 7. 最后再扯两句 ...
- CORS基础要点:关于dataType、contentType、withCredentials
事实上,面试时我喜欢问跨域,因为多数开发者都知道它并且常用,而我希望能从面试者的回答中知道他在这个问题的深入程度,进一步看看面试者研究问题的思维方式及钻研精神,然而确实难到了很多人,当然这也不是面试通 ...
- 第二十七节:Java基础面向对象-静态,单例模式,继承详情知识点
前言 Java基础面向对象-静态,单例模式,继承详情知识点.静态-static关键字,static变量,静态代码块,代码块(不加静态),对象创建过程,单例模式,继承. 静态-static关键字 // ...
- JUnit单元测试基础要点
JUnit单元测试基础要点 1.JUnit是一种测试代码的框架,测试的目的是:保证代码没错,而不是保证代码正确. 2.测试类一般不要和目标类放在一起,但编译成的class文件是放在一起的. 3.单元测 ...
- JavaScript基础入门08
目录 JavaScript 基础入门08 DOM 介绍 绑定事件 给一组元素绑定事件 节点 节点树 节点类型 选取文档内容 通过id选取元素 通过指定的标签名选取元素 用指定的css类来选取元素 通过 ...
- 068 01 Android 零基础入门 01 Java基础语法 08 Java方法 06 参数传递问题——基本数据类型传值
068 01 Android 零基础入门 01 Java基础语法 08 Java方法 06 参数传递问题--基本数据类型传值 本文知识点:参数传递问题--基本数据类型传值 说明:因为时间紧张,本人写博 ...
随机推荐
- 你以为你了解最常用的string.substring()的几个常见问题吗?
---恢复内容开始--- 前言: 1.项目中我们难免会用到各种对字符串的处理方法,可是你曾知道substring()这个用法别有洞天?你考虑过一下几个情况吗? 使用Substring()时的正确写法: ...
- ASP.NET-FineUI开发实践-8
上回模拟的是下拉grid,这回我把下拉grid和表格自动补全放一起了,实在是好做,但是也有很多要注意的,现在分享下,大家学习. 接上回 传送门 1. 有个tbxMyBox1_TriggerClick ...
- asp.net微信开发第九篇----模板消息的使用
微信平台的模板消息,使用起来非常好,效果如下: 和平时我们微信中关注信用卡官方微信,如果消费了,信用卡官方微信就返回一个模板消息给我们告知,余额还有多少,消费了多少. 使用的步骤,我只简单介绍了怎么使 ...
- exp导出出现:ORA-00904: "POLTYP": invalid identifier
相关文章: <exp导出出现:ORA-00904: : invalid identifier>:http://blog.itpub.net/23135684/viewspace-13 ...
- MySQL中的binlog相关命令和恢复技巧
操作命令: 复制代码 代码如下: show binlog events in 'mysql-bin.000016' limit 10; reset master 删除所有的二进制日志 flush lo ...
- Zend Framework
参考:http://www.php100.com/manual/ZendFramework/index.html 1.1. 概述 Zend Framework (ZF) 是一个开放源代码的 PHP5 ...
- 1.一个.java源文件中是否可以包括多个类?2...
1.一个“.java”源文件中是否可以包括多个类(不是内部类)?有什么限制? 答:可以有多个类,但只能有一个public类,并且public的类名必须与文件名相一致. 2.java有没有goto? 答 ...
- 网页通用的测试用例(出处:: 51Testing-- lxp1119216)
此题的考察目的:面试者是否熟悉各种测试方法,是否有丰富的Web测试经验, 是否了解Web开发,以及设计Test case的能力 这个题目还是相当有难度的, 一般的人很难把这个题目回答好. 首先,你要了 ...
- 高级应用与部署 —— 主程序与web目录分离
在网站部署中,考虑网站的安全行问题,可以将您的网站主程序与web目录分离,使主程序在web目录之外,从而提高网站的安全性. 分离方法 1.将phpcms v9中程序主框架目录phpcms移动至web目 ...
- Python----Tornado安装
Tornado安装,环境准备: 1.python安装包及安装 2.Tornado安装包 Python包安装 Linux下安装 如果使用的是 Linux系统 或 Mac OS X ,系 ...