static 与单例模式、auto_ptr与单例模式、const 用法小结、mutable修饰符
一、static 与单例模式
单例模式也就是简单的一种设计模式,它需要:
保证一个类只有一个实例,并提供一个全局访问点
禁止拷贝
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#include <iostream>
using namespace std; class Singleton ~Singleton() Singleton *Singleton::instance_; int main(void) Singleton *s1 = Singleton::GetInstance(); //Singleton s3(*s1); // 调用拷贝构造函数 return 0; |
上述程序虽然调用了两个GetInstance函数,但只调用一次构造函数,即创建一个对象。将赋值运算符和拷贝构造函数声明为私有,禁止拷贝。但程序存在一个问题就是对象生存期到时不会被析构。
为了解决对象不会被析构的问题,可以使用一个静态的嵌套类对象来解决:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
#include <iostream>
using namespace std; class Singleton {
instance_ = new Singleton; }
return instance_; }
~Singleton() //static void Free() // {
// delete instance_; // }
//} class Garbo {
delete instance_; }
} }; private: Singleton(const Singleton &other); Singleton &operator=(const Singleton &other); Singleton() { cout << "Singleton ..." << endl; } static Singleton *instance_;
static Garbo garbo_; // 利用对象的确定性析构
}; Singleton::Garbo Singleton::garbo_;
int main(void)
{ //Singleton s1; //Singleton s2; Singleton *s1 = Singleton::GetInstance(); //Singleton s3(*s1); // 调用拷贝构造函数 return 0; |
利用静态嵌套对象的确定性析构会调用Garbo类的析构函数,在析构函数内delete 单例类的指针。
上面办法比较繁琐,也可以返回局部静态对象的引用来解决:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#include <iostream>
using namespace std; class Singleton ~Singleton() private: int main(void) return 0; |
局部静态对象只会初始化一次,所以调用多次GetInstance函数得到的是同一个对象。由于函数内使用了静态对象,故不是线程安全的。实际上也可以使用auto_ptr 智能指针 来解决,程序如下,更详细的对auto_ptr 的讨论参见这里。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <iostream>
#include<memory> using namespace std; class Singleton ~Singleton() auto_ptr<Singleton> Singleton::instance_; int main(void) Singleton *s1 = Singleton::GetInstance(); //Singleton s3(*s1); // 调用拷贝构造函数 return 0; |
实际上,上述所有的单例模式例子都不是线程安全的,设想如果两个线程同时运行到语句if (instance
== null),而此时该实例的确没有创建,那么两个线程都会创建一个实例。如果不希望加锁实现线程安全,可以使用饿汉模式(即在main函数之前先生成一个实例):
或者通过加锁方式实现,请参考这里。
二、const成员函数、const 对象、mutable修饰符
(一)、const 成员函数
const成员函数不会修改对象的状态
const成员函数只能访问数据成员的值,而不能修改它
(二)、const 对象
如果把一个对象指定为const,就是告诉编译器不要修改它
const对象的定义:
const 类名 对象名(参数表);
const对象不能调用非const成员函数
用mutable修饰的数据成员即使在const对象或在const成员函数中都可以被修改。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
#include <iostream>
using namespace std; class Test } int GetX() void Output() const int GetOutputTimes() const mutable int outputTimes_; int main(void) Test t2(20); t.Output(); |
三、const 用法总结
可以对const 的用法做个小总结:
参考:
C++ primer 第四版
Effective C++ 3rd
C++编程规范
static 与单例模式、auto_ptr与单例模式、const 用法小结、mutable修饰符的更多相关文章
- c++ const用法小结
const用法 1,定义全局变量的内存分配问题 #define Pi_1 3.14 //使用#define宏 const double Pi_2 = 3.14 //使用const ...
- C++ const用法小结 (欢迎大家拍砖)
C++const 关键字小结 const 是constant的缩写,本意是不变的,不易改变的意思. const 在C++中是用来修饰内置类型变量,自定义对象,成员函数,返回值,函数参数. 一.cons ...
- C#中的readonly跟const用法小结
总结一下常量和只读字段的区别: 由来: 笔者也是在看欧立奇版的<.Net 程序员面试宝典>的时候,才发现自己长久以来竟然在弄不清出两者的情况下,混用了这么长的时间.的确,const与rea ...
- CPP-基础:非静态成员函数后面加const,以及mutable修饰成员变量
非静态成员函数后面加const(加到非成员函数或静态成员后面会产生编译错误),表示成员函数隐含传入的this指针为const指针,决定了在该成员函数中,任意修改它所在的类的成员的操作都是不允许的(因为 ...
- const用法小结
const与指针 char *const p --> char *(const p) --> 指针常量 char const *p --> char (const *p) --> ...
- C++的那些事:const用法面面观
一.const是什么 在 C/C++ 语言中,const关键字是一种修饰符.所谓“修饰符”,就是在编译器进行编译的过程中,给编译器一些“要求”或“提示”,但修饰符本身,并不产生任何实际代码.就 con ...
- C/C++ 中 const 修饰符用法总结
C/C++ 中 const 修饰符用法总结 在这篇文章中,我总结了一些C/C++语言中的 const 修饰符的常见用法,供大家参考. const 的用法,也是技术性面试中常见的基础问题,希望能够帮大家 ...
- C++中const用法详解
本文主要内容来自CSDN论坛: http://bbs.csdn.net/topics/310007610 我做了下面几点补充. 补充: 1. 用const声明全局变量时, 该变量仅在本文件内可见, 类 ...
- [原创] 基础中的基础(二):C/C++ 中 const 修饰符用法总结
在这篇文章中,我总结了一些C/C++语言中的 const 修饰符的常见用法,供大家参考. const 的用法,也是技术性面试中常见的基础问题,希望能够帮大家梳理一下知识,给大家一点点帮助.作者是菜鸟一 ...
随机推荐
- centos的linux内核源码下载方法
http://vault.centos.org/ http://blog.csdn.net/xiongzhizhu/article/details/51816243
- 使用 HAProxy, PHP, Redis 和 MySQL 轻松构建每周上亿请求Web站点
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- cocos2d-x HelloWorld 代码一撇
本节简单对新生成的hellowrold 项目相关代码进行简单分析,具体以代码注释的方式展示给大家.代码相对简单些,在此不作过多赘述,直接上码: int APIENTRY _tWinMain(H ...
- javascript转换日期字符串为Date对象
把一个日期字符串如“2007-2-28 10:18:30”转换为Date对象: 1: var strArray=str.split(" "); var strDate=strArr ...
- js 操作select和option常用代码整理
1.获取选中select的value和text,html代码如下: <select id="mySelect"> <option value="1&qu ...
- easyui 设置一加载,搜索框立即弹出的效果
1.部分html文件 <div id="searchForm" region="north" title="标的查询" collaps ...
- hadoop中实现定制Writable类
Hadoop中有一套Writable实现可以满足大部分需求,但是在有些情况下,我们需要根据自己的需要构造一个新的实现,有了定制的Writable,我们就可以完全控制二进制表示和排序顺序. 为了演示如何 ...
- 【转】6 Reasons Why JavaScript’s Async/Await Blows Promises Away (Tutorial)
原文:https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec105 ...
- ArcGIS Add-In调试无法重新生成
在调试ArcGIS Add-In时,出现错误:无法注册程序集"……\Projects\ArcGISAddIn\ArcGISAddIn\bin\Debug\ArcGISAddIn.dll&qu ...
- android gallery 自定义边框+幻灯片效果
最近在项目中用到图片轮播,试了Gallery,ViewFlipper,ViewPager,感觉Gallery最符合需求,但是Gallery的系统边框很难看,项目中要求用自己的背景图片. 下面来看一下使 ...