找回密码
 注册
搜索
热搜: 回贴
  • 前程无忧官网首页 有什么好的平台可以
  • 最新的销售平台 互联网营销的平台有哪
  • 制作网页的基本流程 网页制作和网页设
  • 【帝国CMS】输出带序号的列表(数字排
  • 网站建设公司 三一,中联,极东泵车的
  • 织梦 建站 织梦网站模版后台怎么更改
  • 云服务官网 哪些网站有免费的简历模板
  • 如何建网站要什么条件 建网站要用什么
  • 吉林市移动公司电话 吉林省退休人员网
  • 设计类毕业论文 网站设计与实现毕业论
查看: 1124|回复: 9

[原创]Singleton的C++实现 及相关问题

[复制链接]
发表于 2009-11-3 02:57:57 | 显示全部楼层 |阅读模式 IP:江苏扬州
编程序的时候很多情况下要求当前的程序中只有一个object。例如一个程序只有一个和数据库的连接,只有一个鼠标的object。
最简单的方法是用个全局变量或者用个静态变量。但这违反基本的Object Oriented Design 的原则,使程序执行的整体结构,可读性以及可维护大大下降。同时如果所编写的程序不是主程序而是dll的话全局变量的寿命更难控制。
Design Pattern 中最简单也是应用最广的就是Singleton, 就是用于解决这个问题的。下面是一个简单的Singleton的C++的实现,应用这个class之后可以保证当前程序中只有一个copy 。
Class Singleton
{
public:
static Singleton * GetInstance()
{
static Singleton instance;
return &instance;
}
protected:
Singleton();
~Singleton();
}
由于constructor和destructor都是protected,所以无法直接生成这个class。使用时直接用 Singleton::GetInsgtance()就行了。不必操心Singleton的寿命。

另一种实现方法如下:

Class Singleton
{
public:
static Singleton * GetInstance()
{
if(!m_pInstance)
m_pInstance = new Singleton();
return pinstance;
}
private:
static Singleton *m_pInstance;
protected:
Singleton();
~Singleton();
}
这种写法的问题在于你需要在new 之后的适当时候delete 掉这个Instance。这个寿命很难控制。但有的人说这个实现是thread_safe的。
而第一个不是thread_safe 。

我瞧了N天也没有发现这个实现怎么thread safe。经多家讨论后证明这个实现合第一个一样不thread safe。两个进程同时进入GetInstance同时m_pInstance还是NULL,同时constructor花的时间特别长的时候就可能出事。要将其用在多进程的程序中的时候最好在GetInstance函数的开始和结束加上“Cretical Section”。

当我学完这一段的时候发现他竟然不能用在我的project里,因为我的project里要管理的这个object可能有几个copy(数量确定)。那么就需要把上面的概念稍微扩展一下。把static Singleton instance换成数组或者vector。这样能够生成的数量是确定的。使用者不会因为多用几次GetInstance而改变了内存的管理。当然用户用GetInstance()的时候应该知道自己要Get哪个copy,给GetInstance()加个参数。稍微复杂一点。
发表于 2009-11-3 02:57:58 | 显示全部楼层 IP:江苏扬州
斑竹加油
回复

使用道具 举报

发表于 2009-11-3 02:58:00 | 显示全部楼层 IP:江苏扬州
呵呵,支持下myajax95
至于第二种实现方法我觉得应该不是thread_safe
假设两条线程a,b同时调用了这个函数,线程a执行到m_pInstance = new Singleton()语句前,系统切换到线程b,然后线程b判断m_pInstance还是空,于是执行m_pInstance = new Singleton()语句来new一个对象,这时问题就大了,不管怎样,这时已经有内存泄漏。
所以我和myajax95的想法一样,多线程下执行类似这种赋值语句的话最好加上信号量等进行互斥,或者windows的Cretical Section
回复

使用道具 举报

发表于 2009-11-3 02:58:01 | 显示全部楼层 IP:江苏扬州
to aogun:
你的头像老是在换,我自己也去做了一个,呵呵,好看不?
回复

使用道具 举报

发表于 2009-11-3 02:58:02 | 显示全部楼层 IP:江苏扬州
to wfpb:
不打算再换了,本来想用一个动态头像的,后面想想还是不要给论坛服务器增加负担了,你的头像中的wfpb几个字最好再大点
呵呵,下次闲话最好不要在精华贴中说,不然myajax95兄会怪我们糟蹋了他的帖子
回复

使用道具 举报

发表于 2009-11-3 02:58:03 | 显示全部楼层 IP:江苏扬州
wfpb,总是说话不符合场合
也不看看这什么地方
myajax
大哥说的都是我们以后要犯的错误,经验之谈,难得可贵.
严肃点,严肃点
回复

使用道具 举报

发表于 2009-11-3 02:58:03 | 显示全部楼层 IP:江苏扬州
to aogun:
你的头像老是在换,我自己也去做了一个,呵呵,好看不?



讲实话.....*是很好看.

有个字被过滤了! :)
回复

使用道具 举报

发表于 2009-11-3 02:58:05 | 显示全部楼层 IP:江苏扬州
myajax,aogun
呵呵,各位前辈
眼看着我的C++之旅就要完成,升如大二
所以我发扬我的风格,立下军令状
大二之前在C++方面(仅此方面)超过你们
你们就等着吧(很强的动力)
我喜欢给自己一些伟大的要求,同时
请你们在我闭门修行时在这里的问题能不计赐教。。
有问题我会去问你们的。
呵呵,同时希望大家C++进步
回复

使用道具 举报

发表于 2009-11-3 02:58:06 | 显示全部楼层 IP:江苏扬州
眼看着我的C++之旅就要完成,升如大二
所以我发扬我的风格,立下军令状
大二之前在C++方面(仅此方面)超过你们
的确是很大的目标
回复

使用道具 举报

发表于 2009-11-3 02:58:07 | 显示全部楼层 IP:江苏扬州
最好早点比我强,我再有问题的时候就不用在英文网站上求爷爷告奶奶的问人了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )

GMT+8, 2024-9-30 11:33 , Processed in 0.299834 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表