| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1722 人关注过本帖
标题:[原创]Singleton的C++实现 及相关问题
只看楼主 加入收藏
myajax95
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:30
帖 子:2978
专家分:0
注 册:2006-3-5
收藏
 问题点数:0 回复次数:13 
[原创]Singleton的C++实现 及相关问题

编程序的时候很多情况下要求当前的程序中只有一个object。例如一个程序只有一个和数据库的连接,只有一个鼠标的object

最简单的方法是用个全局变量或者用个静态变量。但这违反基本的Object Oriented Design 的原则,使程序执行的整体结构,可读性以及可维护大大下降。同时如果所编写的程序不是主程序而是dll的话全局变量的寿命更难控制。

Design Pattern 中最简单也是应用最广的就是Singleton, 就是用于解决这个问题的。下面是一个简单的SingletonC++的实现,应用这个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()加个参数。稍微复杂一点。

搜索更多相关主题的帖子: Singleton 
2006-06-01 12:13
song4
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:38
帖 子:1533
专家分:4
注 册:2006-3-25
收藏
得分:0 

斑竹加油

嵌入式 ARM 单片机 驱动 RT操作系统 J2ME LINUX  Symbian C C++ 数据结构 JAVA Oracle 设计模式 软件工程 JSP
2006-06-01 12:20
aogun
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:638
专家分:0
注 册:2006-4-5
收藏
得分:0 
呵呵,支持下myajax95
至于第二种实现方法我觉得应该不是thread_safe
假设两条线程a,b同时调用了这个函数,线程a执行到m_pInstance = new Singleton()语句前,系统切换到线程b,然后线程b判断m_pInstance还是空,于是执行m_pInstance = new Singleton()语句来new一个对象,这时问题就大了,不管怎样,这时已经有内存泄漏。
所以我和myajax95的想法一样,多线程下执行类似这种赋值语句的话最好加上信号量等进行互斥,或者windows的Cretical Section

世界上总共有 10 种人,一种懂得什么是二进制 ,一种不懂。
2006-06-01 14:18
wfpb
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:2188
专家分:0
注 册:2006-4-2
收藏
得分:0 
to aogun:
你的头像老是在换,我自己也去做了一个,呵呵,好看不?

[glow=255,red,2]wfpb的部落格[/glow] 学习成为生活的重要组成部分!
2006-06-01 15:36
aogun
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:638
专家分:0
注 册:2006-4-5
收藏
得分:0 
to wfpb:
不打算再换了,本来想用一个动态头像的,后面想想还是不要给论坛服务器增加负担了,你的头像中的wfpb几个字最好再大点
呵呵,下次闲话最好不要在精华贴中说,不然myajax95兄会怪我们糟蹋了他的帖子

世界上总共有 10 种人,一种懂得什么是二进制 ,一种不懂。
2006-06-01 16:51
song4
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:38
帖 子:1533
专家分:4
注 册:2006-3-25
收藏
得分:0 
wfpb,总是说话不符合场合
也不看看这什么地方
myajax
大哥说的都是我们以后要犯的错误,经验之谈,难得可贵.
严肃点,严肃点

嵌入式 ARM 单片机 驱动 RT操作系统 J2ME LINUX  Symbian C C++ 数据结构 JAVA Oracle 设计模式 软件工程 JSP
2006-06-01 21:15
stylev
Rank: 1
等 级:新手上路
威 望:1
帖 子:136
专家分:0
注 册:2006-5-30
收藏
得分:0 

to aogun:
你的头像老是在换,我自己也去做了一个,呵呵,好看不?


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

有个字被过滤了! :)

E-mail/MSN: stylev@
2006-06-02 02:54
song4
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:38
帖 子:1533
专家分:4
注 册:2006-3-25
收藏
得分:0 
myajax,aogun
呵呵,各位前辈
眼看着我的C++之旅就要完成,升如大二
所以我发扬我的风格,立下军令状
大二之前在C++方面(仅此方面)超过你们
你们就等着吧(很强的动力)
我喜欢给自己一些伟大的要求,同时
请你们在我闭门修行时在这里的问题能不计赐教。。
有问题我会去问你们的。
呵呵,同时希望大家C++进步

嵌入式 ARM 单片机 驱动 RT操作系统 J2ME LINUX  Symbian C C++ 数据结构 JAVA Oracle 设计模式 软件工程 JSP
2006-06-03 11:03
wfpb
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:2188
专家分:0
注 册:2006-4-2
收藏
得分:0 
眼看着我的C++之旅就要完成,升如大二
所以我发扬我的风格,立下军令状
大二之前在C++方面(仅此方面)超过你们
的确是很大的目标

[glow=255,red,2]wfpb的部落格[/glow] 学习成为生活的重要组成部分!
2006-06-03 14:35
myajax95
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:30
帖 子:2978
专家分:0
注 册:2006-3-5
收藏
得分:0 
最好早点比我强,我再有问题的时候就不用在英文网站上求爷爷告奶奶的问人了。

http://myajax95./
2006-06-03 14:49
快速回复:[原创]Singleton的C++实现 及相关问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.012979 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved