【asp.net中C++单例实现问题分析】写出一种单例模式
方案一
代码如下 class QMManager{
public:
static QMManager &instance()
{
static QMManager instance_;
return instance_;
}
}
这是最简单的版本,在单线程下(或者是C++0X下)是没任何问题的,但在多线程下就不行了,因为static QMManager instance_;这句话不是线程安全的。
在局部作用域下的静态变量在编译时,编译器会创建一个附加变量标识静态变量是否被初始化,会被编译器变成像下面这样(伪代码):
代码如下 static QMManager &instance(){
static bool constructed = false;
static uninitialized QMManager instance_;
if (!constructed) {
constructed = true;
new(&s) QMManager; //construct it
}
return instance_;
}
这里有竞争条件,两个线程同时调用instance()时,一个线程运行到if语句进入后还没设constructed值,此时切换到另一线程,constructed值还是false,同样进入到if语句里初始化变量,两个线程都执行了这个单例类的初始化,就不再是单例了。
方案二
一个解决方法是加锁:
代码如下 static QMManager &instance(){
Lock(); //锁自己实现
static QMManager instance_;
UnLock();
return instance_;
}
但这样每次调用instance()都要加锁解锁,代价略大。
方案三
那再改变一下,把内部静态实例变成类的静态成员,在外部初始化,也就是在include了文件,main函数执行前就初始化这个实例,就不会有线程重入问题了:
代码如下 class QMManager{
protected:
static QMManager instance_;
QMManager();
~QMManager(){};
public:
static QMManager *instance()
{
return &instance_;
}
void do_something();
};
QMManager QMManager::instance_; //外部初始化
这被称为饿汉模式,程序一加载就初始化,不管有没有调用到。
看似没问题,但还是有坑,在一个2B情况下会有问题:在这个单例类的构造函数里调用另一个单例类的方法可能会有问题。
看例子:
代码如下//.h
class QMManager
{
protected:
static QMManager instance_;
QMManager();
~QMManager(){};
public:
static QMManager *instance()
{
return &instance_;
}
};
class QMSqlite
{
protected:
static QMSqlite instance_;
QMSqlite();
~QMSqlite(){};
public:
static QMSqlite *instance()
{
return &instance_;
}
void do_something();
};
QMManager QMManager::instance_;
QMSqlite QMSqlite::instance_;
//.cpp
QMManager::QMManager()
{
printf("QMManager constructorn");
QMSqlite::instance()->do_something();
}
QMSqlite::QMSqlite()
{
printf("QMSqlite constructorn");
}
void QMSqlite::do_something()
{
printf("QMSqlite do_somethingn");
}
这里QMManager的构造函数调用了QMSqlite的instance函数,但此时QMSqlite::instance_可能还没有初始化。
这里的执行流程:程序开始后,在执行main前,执行到QMManager QMManager::instance_;这句代码,初始化QMManager里的instance_静态变量,调用到QMManager的构造函数,在构造函数里调用QMSqlite::instance(),取QMSqlite里的instance_静态变量,但此时QMSqlite::instance_还没初始化,问题就出现了。
那这里会crash吗,测试结果是不会,这应该跟编译器有关,静态数据区空间应该是先被分配了,在调用QMManager构造函数前,QMSqlite成员函数在内存里已经存在了,只是还未调到它的构造函数,所以输出是这样:
QMManager constructor
QMSqlite do_something
QMSqlite constructor
方案四
那这个问题怎么解决呢,单例对象作为静态局部变量有线程安全问题,作为类静态全局变量在一开始初始化,有以上2B问题,那结合下上述两种方式,可以解决这两个问题。boost的实现方式是:单例对象作为静态局部变量,但增加一个辅助类让单例对象可以在一开始就初始化。如下:
代码如下//.h
class QMManager
{
protected:
struct object_creator
{
object_creator()
{
QMManager::instance();
}
inline void do_nothing() const {}
};
static object_creator create_object_;
QMManager();
~QMManager(){};
public:
static QMManager *instance()
{
static QMManager instance;
return &instance;
}
};
QMManager::object_creator QMManager::create_object_;
class QMSqlite
{
protected:
QMSqlite();
~QMSqlite(){};
struct object_creator
{
object_creator()
{
QMSqlite::instance();
}
inline void do_nothing() const {}
};
static object_creator create_object_;
public:
static QMSqlite *instance()
{
static QMSqlite instance;
return &instance;
}
void do_something();
};
QMManager::object_creator QMManager::create_object_;
QMSqlite::object_creator QMSqlite::create_object_;
结合方案3的.cpp,这下可以看到正确的输出和调用了:
QMManager constructor
QMSqlite constructor
QMSqlite do_something
来看看这里的执行流程:
初始化QMManager类全局静态变量create_object_
->调用object_creator的构造函数
->调用QMManager::instance()方法初始化单例
->执行QMManager的构造函数
->调用QMSqlite::instance()
->初始化局部静态变量QMSqlite instance
->执行QMSqlite的构造函数,然后返回这个单例。
跟方案三的区别在于QMManager调用QMSqlite单例时,方案3是取到全局静态变量,此时这个变量未初始化,而方案四的单例是静态局部变量,此时调用会初始化。
跟最初方案一的区别是在main函数前就初始化了单例,不会有线程安全问题。
最终boost
上面为了说明清楚点去除了模版,实际使用是用模版,不用写那么多重复代码,这是boost库的模板实现:
代码如下template <typename T>
struct Singleton
{
struct object_creator
{
object_creator(){ Singleton<T>::instance(); }
inline void do_nothing()const {}
};
static object_creator create_object;
public:
typedef T object_type;
static object_type& instance()
{
static object_type obj;
//据说这个do_nothing是确保create_object构造函数被调用
//这跟模板的编译有关
create_object.do_nothing();
return obj;
}
};
template <typename T> typename Singleton<T>::object_creator Singleton<T>::create_object;
class QMManager
{
protected:
QMManager();
~QMManager(){};
friend class Singleton<QMManager>;
public:
void do_something(){};
};
int main()
{
Singleton<QMManager>::instance()->do_something();
return 0;
}
其实Boost库这样的实现像打了几个补丁,用了一些奇技淫巧,虽然确实绕过了坑实现了需求,但感觉挺不好的。
- 【asp.net中C++单例实现问题分析】写出一种单例模式 相关文章:
- 爱情文章
- 亲情文章
- 友情文章
- 随笔
- 哲理
- 励志
- 范文大全
-
小米电视恢复出厂设置 [小米电视怎么恢复出厂设置教程?]
现在很多人买小米系列产品,现在小米电视卖的也很好,那么小米电视怎么恢复出厂设置教程?下面分享小米电视
【爱情文章】 日期:2020-02-16
-
美团拍店怎么做任务? 美团众包拍店任务什么意思
美团拍店是美团旗下数据采集APP,小伙伴可以通过做任务赚取奖励!随手拍下门店照片电话等即可赚钱哦!那
【爱情文章】 日期:2020-04-19
-
【魅族Pro5通话中如何查看联系人?】通话中查找联系人
当别人打电话给你询问他人的电话号码时,你还在手机上查看后再回拨或短信告知?接下来,大猫教你魅族Pro
【爱情文章】 日期:2020-04-16
-
BIOS参数无法进行设置:蚂蚁保护板参数无法设置
在进入BIOS设置后,无法修改设置的数据,导致这种情况的原因有很多种,各种情况处理方法也不同。1 设
【爱情文章】 日期:2020-04-05
-
小米手机如何批量删除联系人 小米手机如何批量删除联系人(适应
在网上看到很多刚用小米手机的朋友不知道小米手机怎么批量删除联系人,小米手机小米2、小米3、红米等等都
【爱情文章】 日期:2020-02-23
-
苹果iPhone6S开机菜单导航关闭方法 iPhone 6S
苹果iPhone6S开机菜单导航关闭方法。手机每次重启后就会出现“开机菜单导航&rdqu
【爱情文章】 日期:2020-04-16
-
vivo手机怎么设置闹钟背景图片【闹钟ONE怎么更换提醒界面背景图
很多小伙伴都不喜欢闹钟ONE系统默认的背景图片,不喜欢的话可以更换掉,那么怎么更换背景图片呢?现在小
【爱情文章】 日期:2020-04-07
-
[Word表格中内容太多不能全部显示该怎么设置?]表格内容太多不显示
在处理Word表格的时候,我们难免遇到这样的情况:即:表格单元格的文字太多,以至于该单元格无法显示全
【爱情文章】 日期:2020-04-26
-
Win8如何卸载自带播放器 360视频默认播放器
1、使用组合键win+i打开选择“控制面板”2、在控制面板的界面中在右上方的查看方式更改为“小图标”
【爱情文章】 日期:2020-03-15
-
支付宝转送福气卡没收到怎么办|小米旗舰店送福气包
支付宝转送福气卡没收到怎么办问题详情:支付宝转送福气卡,福气一直显示赠送中,好友没有收到,而自己的福
【爱情文章】 日期:2020-03-31
-
【jsp页面中插入css样式的三种方法总结】 在jsp中怎样加入css样式
本篇文章主要是对jsp页面中插入css样式的三种方法进行了总结介绍,需要的朋友可以过来参考下,希望对
【亲情文章】 日期:2020-05-29
-
室内设计原则 室内设计的原则有哪些
(一)室内装饰设计要满足使用功能要求室内设计是以创造良好的室内空间环境为宗旨,把满足人们在室内进行生
【亲情文章】 日期:2018-08-08
-
【在matlab中同一个窗口绘制多个曲线】 matlab绘制曲线的方法
matlab中绘制二维图形有一个能在同一个坐标下绘制多个图案的功能。plot(x1,y1,x2,y2
【亲情文章】 日期:2020-05-29
-
家居防潮法则之客厅篇_客厅颜色搭配法则
防潮第一步从客厅开始,绝对是最明智的选择。试想在阴雨连绵的天气,大部分人必定选择宅在家里,那么客厅就
【亲情文章】 日期:2018-08-09
-
耐用经济窗帘杆的挑选方法_窗帘杆的价格
在现代家居软装饰中,窗帘的功能已不仅仅是有遮挡阳光的功能,更重要的是窗帘能很好衬托居室的装饰风格,窗
【亲情文章】 日期:2018-08-09
-
autoCAD,2007坐标系的建立方法图解:三坐标测量仪怎么建立坐标系图解
适用于:autocad2004、autoCAD2007方法:1、打开cad软件,在cad里绘制一个矩
【亲情文章】 日期:2018-08-08
-
三星s4三种截屏小技巧总有一种适合你 华为截屏小技巧
很多时候,我们在使用手机的时候需要截屏,但是又不知道怎么做。在这里,小编给大家带来三星s4截屏方法。
【亲情文章】 日期:2020-02-12
-
[i5-4690配GTX770显卡实现高端DIY装机图文直播全过程,附配置清单
很多玩家为了提高电脑的性能,选择了自己搭配硬件进行电脑组装,今天教程网小编为大家带来一套定位2015
【亲情文章】 日期:2020-02-11
-
小度wifi插入电脑USB接口后没反应该怎么反应?_小度wifi多少钱一个
wifi是手机上网必备的伙伴,办公室没WIFI,买了个小度wifi使用几天后,插入接口窗口显示:未插
【亲情文章】 日期:2020-02-12
-
机箱前置usb30接主板哪个口_怎么分清电脑主板前置机箱接线?,连接
教你认清主板前置机箱接线,连接主板跳线,装电脑连跳线就这几步,简单吧1、电源开关(POWER)这个开
【亲情文章】 日期:2020-02-09
-
【支付宝小视频如怎么保存?】 支付宝小视频怎么保存到相册
对于今天推出的最新支付宝9 2版本中,支付宝给我们新增了小视频功能,可以实现10秒视频拍摄,这点跟微
【友情文章】 日期:2020-05-05
-
怎么按成绩分班 [巧用WPS快速进行自动分班操作]
前言:分班是教学管理信息化的一个热门话题,一般要用专门的软件,经过试验,用手头上的WPS电子表格,不
【友情文章】 日期:2020-02-29
-
养乐多最短的广告词 养乐多广告语
养乐多广告语:1一百亿个活的养乐多菌帮肠道做运动,肠子漂亮,人就美,活的活的养乐多,越活越开心。2给
【友情文章】 日期:2020-03-16
-
【支付宝删除本地证书和取消证书的区别是什么?】 支付宝电脑版
删除本地证书:可以防止他人用证书登录进行操作。删除后仍然是证书用户,只是把当前机器中安装的证书删除了
【友情文章】 日期:2020-04-07
-
十三步简单入侵个人电脑教程:如何简单入侵苹果手机
木马冰河是一款功能强大的远程控制软件,因为它的功能很强大所以成为了黑客们发动入侵的工具,2HK联盟M
【友情文章】 日期:2020-03-14
-
店铺跳失率多少正常【淘宝店铺跳失率高怎么解决】
1 首页布局没有根据人群浏览习惯吸引买家眼球浏览更多的屏幕数,首页跳失率高;我们都知道淘宝店铺首页装
【友情文章】 日期:2020-03-05
-
[一起作业怎么刷学豆]一起作业无限学豆软件
一起作业怎么刷学豆?一起作业怎么得学豆?一起作业是一款非常好用的帮助孩子学习的教育学习平台,在一起作
【友情文章】 日期:2020-03-27
-
[淘宝直通车图片创意对比测试实例(用数据说话)]淘宝开直通车多
“我也不想的,可是老板说这个图好看,我们就一直用这个图。”某日小车听到某运营
【友情文章】 日期:2020-02-28
-
电脑上做美篇图片怎么添加 电脑上的图片显示不了,用美图看看可
很多电脑用户都会遇到这样的问题,那就是电脑上的图片显示不了,可能很多网友会选择放弃这个图片,或者重新
【友情文章】 日期:2020-03-14
-
范冰冰的直播号是多少【花椒直播范冰冰直播间id是多少】
花椒直播已经和范冰冰正式签约!范爷将担任花椒直播首席体验官!那么范冰冰花椒直播间id是多少。范冰冰花
【友情文章】 日期:2020-03-07
-
【清除顽固病毒的方法】 怎样删除电脑顽固病毒
有些病毒非常的顽固,在删除后等你重启电脑,它又来了,一起看看清除顽固病毒的方法。一、清空Intern
【生活随笔】 日期:2020-05-29
-
Redmine+SQL,SERVER在Windows下的安装 Windows下安装grub
我们一直用Redmine做管理项目和系统缺陷跟踪 最近中心开发了微信平台,并引入了电话系统,都是SQ
【生活随笔】 日期:2020-05-29
-
【CPU超频所导致的电脑系统蓝屏的有效解决方法】CPU超频
CPU超频容易损坏硬件,影响CPU的寿命。但是对于许多电脑发烧友来说,超频可以在已有的硬件基础上花少
【生活随笔】 日期:2020-02-09
-
浜崎真绪所有作品百度云盘_360云盘手机版想分享视频给所有朋友怎
可以使用云盘朋友圈,选择发送给所有的好友,这样他们都可以看到了,直是简单方便呢。图示:
【生活随笔】 日期:2020-04-07
-
【卧室床单搭配术】卧室床单适合什么颜色
众所周知,卧室是提供家人休息、睡觉的场所,其装修设计应追求舒适与宁静。随着人们生活品质生活的提升,如
【生活随笔】 日期:2018-08-09
-
【诠释LED显示屏控制系统之异步控制方式】 LED显示屏控制系统
LED显示屏控制方式有两种,一是同步控制方式,二是异步控制方式。同步控制方式是指:LED屏同步显示电
【生活随笔】 日期:2018-08-09
-
[三星UA55ES8000有网络端口(LAN)端口吗]三星UA55ES800
三星UA55ES8000有1个网络端口(LAN)端口。
【生活随笔】 日期:2020-03-22
-
非阿里巴巴集团网站购物流程_免税店购物流程
1以美团网为例,各网站实际操作流程会有不同,请以实际操作页面提示为准。如:打开美团网(),找到需要购
【生活随笔】 日期:2020-04-10
-
【怎么让美食显得更加诱人的拍摄技法】 彩蛋技法
古代皇帝用膳先得请一个人先替自己尝两口,等别人吃完过一会儿一看没事,好,这菜没被下毒,这就可以放心吃
【生活随笔】 日期:2020-03-18
-
PhotoShop制作泼墨山水风景画_水彩风景画详细步骤图
中国画以水调墨,在生宣纸上用墨色的浓淡变化绘出美丽的画面。下面我们用Photoshop将一幅照片处理
【生活随笔】 日期:2020-04-05
-
[serverx病毒怎么清理] 一键手机清理应用
第一步:开始--运行输入regedit确定进入注册表删除如下项:[HKEY_CURRENT_USER
【人生哲理】 日期:2020-05-29
-
cpu的风扇1155针与775针有什么区别? cpu和风扇都要涂硅脂吗
cpu的风扇1155针与775针有什么区别?775的4个脚的距离是7 2CM,1155的4个脚的距离
【人生哲理】 日期:2020-02-09
-
艺术字体图片 转换器 [使用彩影实现炫酷字体倒影特效]
倒影特效在很多地方都会用到,比如个人相片注释、产品展示、标题设计、网页图片、广告等。今天小编将向大家
【人生哲理】 日期:2020-05-29
-
手绘一级减速器装配图 浩辰CAD机械教程之减速器主视图绘制
在前几期的CAD教程中,我们为大家介绍了使用浩辰CAD机械2011绘制二级齿轮减速器装配图的部分技巧
【人生哲理】 日期:2018-08-08
-
电视出镜记者的运用技巧和误区【杀毒技巧及6大杀毒误区】
一、一般方法1、请升级你的杀毒软件到最新版本,保证病毒库是最新的。2、对于联网的用户,在杀毒之前请断
【人生哲理】 日期:2020-05-29
-
3d模型的黑色背面怎么变成透明_怎么把图片黑色全部变成透明
我们在单面建立前面模型的时候是希望悲鸣能透明,而不挡住后面的模型。1:建立我们需要的单面墙体,然后给
【人生哲理】 日期:2018-08-08
-
[浩辰建筑教程之轴号编辑(添补、重排、倒排轴号)]添补轴号
使用浩辰建筑软件轴网绘制和轴网标注好后,轴号有时候还需要进行处理。譬如:增加轴号,倒排轴号,或轴号的
【人生哲理】 日期:2018-08-08
-
中兴Z9,Max/Z9,Mini开箱测评:中兴手机刷机教程图解
为了满足消费者的不同需求,不少手机厂商都推出了尺寸各异的设备。3月下旬的时候,中兴在北京演艺中心召开
【人生哲理】 日期:2020-02-16
-
CAD绘制璀璨的钻石戒指:CAD钻石
这篇教程教三联的朋友们用AutoCAD绘制璀璨的钻石戒指,教程难度不大。转发过来和三联的朋友们一起学
【人生哲理】 日期:2018-08-08
-
【路由器死机的四大原因分析】 路由器桥接设置图解
经常会在网上看到诸多网友在购买宽带路由器以后,在使用过程中遇到死机频繁掉线问题,给网友带来很多不便,
【人生哲理】 日期:2020-02-16
-
Apple,Watch在表盘上添加文字与符号的方法:小车表盘上符号
很多苹果手表AppleWatch的用户都知道怎么更换表盘的图片,那么,大家知道怎么在表情上显示自己的
【励志文章】 日期:2020-03-19
-
AMD,760K与AMD,860K哪个好?AMD速龙ii,X4,860K和760K区别对比介绍|AMD速龙IIX4
近日AMD推出了新一代屏蔽核显,可超频的AMD速龙iiX4860k四核处理器,该处理器主要用户取代上
【励志文章】 日期:2020-02-09
-
美团怎么买学生票 美团团购怎么购买学生票
接下来小编就教大家美团团购购买学生票方法。1)打开美团团购进入应用后【向左拨动】功能栏,接着点击【火
【励志文章】 日期:2020-04-15
-
监控sd卡显示不存在 安卓手机sd卡不存在是什么原因
1、请确保你的手机中装有SD卡,且SD卡无损坏;2、请确保你的SD卡接触良好,在“设置-
【励志文章】 日期:2020-05-21
-
[麦当劳店面设计分析] 麦当劳在中国有多少店面
店面设计:麦当劳店面设计成功分析近乎一样的快餐产品,近乎一样的店面设计,乐天利与麦当劳为什么却有天壤
【励志文章】 日期:2018-08-08
-
12308汽车票 [12308汽车票包车方法]
12308汽车票包车方法。想要多人结伴去游玩?或者想要同伴一起回家?一起来包车吧!时间方面更自由。那
【励志文章】 日期:2020-04-07
-
我的咖啡学习过程 mcafee mcafee,8.5i,安装过程中出现McAfee,F
确认有足够的权限启动系统服务。”按“忽略(I)”才能继续安装,但最后还是不能升级。经过不断摸索,上官
【励志文章】 日期:2020-03-29
-
【宝贝主图帮助拉动流量】 站外投放如何进行拉动流量
如果说你有去亲自去搜索过淘宝你想要的产品话,那你就要想想在一大堆产品里面吸引你去点击的主图是什么样的
【励志文章】 日期:2020-05-29
-
手机文件怎么上传到钉盘【钉钉如何在钉盘中设置上传的文件其他人
无法设置,隐私文件可以放到企业群文件夹中,只要企业群成员才可以查看;
【励志文章】 日期:2020-04-10
-
【利用wps文字制作一张漂亮的座位表】如何用wps制作座位表
在如今的生活年代里,学校教室,体育赛场,公司会议,演唱会,晚会,聚会,乘车坐船等很多场所,常常涉及到
【励志文章】 日期:2020-05-25
-
食品安全演讲稿1000字具有代表性的6篇
食品安全演讲稿1000字具有代表性的6篇食品安全演讲稿1000字具有代表性的篇1各位老师、同学:上午
【范文大全】 日期:2024-04-29
-
2022年社区矫正人员思想情况汇报
在社区矫正期间,通过司法工作人员,社区工作人员及我所在单位领导的教育,我一直在加强法律知识的学习,自己的思想、工作、学习等方面还存在着许多的不足:首先,在思想上,...
【范文大全】 日期:2024-04-29
-
在全区安全生产工作例会上的讲话【精选推荐】
为进一步明确责任、强化措施、狠抓落实,确保安全生产工作取得扎实成效。下面,结合我X安全生产工作实际,我强调三个方面的意见。一、强化对安全生产严峻形势的认识,切实抓好...
【范文大全】 日期:2024-04-29
-
研讨发言写作框架30例,启发思路
1 打好“信念”加强针,立场坚定方能守住初心。打好“本领”加强针,实干担当方能有所作为。打好“规矩”加强针,严于律己方能行稳致远。2 千山万水不忘来时路,坚定“一心...
【范文大全】 日期:2024-04-29
-
最美少年演讲稿初中生3篇
最美少年演讲稿初中生3篇最美少年演讲稿初中生篇112位“最美孝心少年”的事迹,让现场观众频频抹泪。今
【范文大全】 日期:2024-04-29
-
小学生爱国演讲稿范文5篇
小学生爱国演讲稿范文5篇小学生爱国演讲稿范文篇1各位老师各位同学:大家好!今天我演讲的题目是《我爱你
【范文大全】 日期:2024-04-29
-
办公室思想汇报
【篇一】办公室人员的思想汇报敬爱的党组织:自2020年x月份调入行办公室以来,本人始终注意认真学习,勤奋工作,尊重领导,团结同志,充分履行工作职责,较好地完成了以信息宣...
【范文大全】 日期:2024-04-29
-
关于真诚的演讲稿5篇
关于真诚的演讲稿5篇关于真诚的演讲稿篇1各位领导、各位朋友:大家好!我今天演讲的题目是“真诚·微笑与
【范文大全】 日期:2024-04-29
-
护士入党积极分子思想汇报2000字
敬爱的党组织:经过近一段时间的学习和护士长的帮助,本人在思想上取得了很大的进步,在工作中向优秀同志看齐,对护理工作的认识更加深刻。现将本人近期思想情况汇报如下1、加...
【范文大全】 日期:2024-04-29
-
2022年4月党员思想汇报:为人民服务
思想汇报范文敬爱的党组织:满是收获的xx年已过,我们迎来了布满希看的xx年,新年伊始,我们迎来了xx年。在这新的姨奶奶里我们要有自己的理想和目标,更要为了自己的理想而奋...
【范文大全】 日期:2024-04-29