没有了static, Singleton怎么办?

<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:1; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:0 0 0 0 0 0;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610611985 1073750139 0 0 159 0;} @font-face {font-family:新宋体; panose-1:2 1 6 9 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@新宋体"; panose-1:2 1 6 9 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} h1 {mso-style-priority:9; mso-style-unhide:no; mso-style-qformat:yes; mso-style-link:"标题 1 Char"; mso-style-next:正文; margin-top:17.0pt; margin-right:0cm; margin-bottom:16.5pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:240%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:1; font-size:22.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-font-kerning:22.0pt;} p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph {mso-style-priority:34; mso-style-unhide:no; mso-style-qformat:yes; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; text-indent:21.0pt; mso-char-indent-count:2.0; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} span.1Char {mso-style-name:"标题 1 Char"; mso-style-priority:9; mso-style-unhide:no; mso-style-locked:yes; mso-style-link:"标题 1"; mso-ansi-font-size:22.0pt; mso-bidi-font-size:22.0pt; mso-font-kerning:22.0pt; font-weight:bold;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:437336535; mso-list-type:hybrid; mso-list-template-ids:-1305449064 558520516 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l0:level1 {mso-level-tab-stop:none; mso-level-number-position:left; margin-left:39.0pt; text-indent:-18.0pt;} @list l1 {mso-list-id:678120701; mso-list-type:hybrid; mso-list-template-ids:1203147684 -156753692 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l1:level1 {mso-level-tab-stop:none; mso-level-number-position:left; margin-left:39.0pt; text-indent:-18.0pt;} @list l2 {mso-list-id:2057003552; mso-list-type:hybrid; mso-list-template-ids:-1968939722 -1554222414 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l2:level1 {mso-level-tab-stop:none; mso-level-number-position:left; margin-left:39.0pt; text-indent:-18.0pt;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->

Singleton 的标准实现

Singleton 模式是 GOF 23 个模式中最简单地,也是使用地比较广泛地一个模式。其结构如下图所示 :


其实现大家应该都很了解,不了解的就 Google 一下,要多少有多少,也可以参考附件中的 SingletonStd

生活有时不那么美好

         Singleton C++ 实现依赖于静态变量的使用,在可以使用静态变量的环境中,生活是美好的,可是这个世界上也存在不支持静态变量 (Brew,Symbian ,etc) 或者对静态变量的使用有诸多限制 (Brew Mobile Platform 不能在函数中使用静态变量 ) 的平台。在这种情况,你可能会嘟囔地骂编译器,并发誓说没有这个模式照样可以工作,但是我可以打赌,你不是认真地,你只不过是发发牢骚而已,最后要面对的依然是怎样让才能让 Singleton work 起来。

         在实际工作中,我采用一种比较直接的方案,现记录下来以飨大家,同时欢迎大家多多拍砖,只是在拍的同时务请告知更好地解决办法。

搁哪儿啊

         在你接受了现实,并开始思考解决方案的时候,第一个拦在你面前问题一定是: Singleton 该搁哪儿?天无绝人之路,对于不能使用静态变量的平台,一般来说都有一个代表那个 applet 的实例,它在程序启动时创建,在程序结束时销毁。而且会提供一个 help function ,让你可以在程序的任意地方获得这个实例。为了叙述方便,我把这个 Applet 取名为 AppInstance, 那个可以获取它 help function GetAppInstance() 。这样我们就可以把 Singleton 存在这个 AppInstance 中。可以在控制台中这样模拟 AppInstance GetAppInstance:

#ifndef APPINSTANCE_HPP

#define APPINSTANCE_HPP

#include <vector>

#include <map>

#include <string>

using std::vector;

using std::string;

using std::map;

typedef void (*releaseFun)(void );

 

class AppInstance

{

public :

     ~AppInstance();

     static AppInstance* GetInstance();

     void RegisterSingleton(const string& strName,void * pSingleton);

     void RegisterSingletonReleaseFun(releaseFun relFun);

     void *& GetSingleton(const string& strName);

private :

     map<string,void *>  m_vSingleton;                        //store the instance of Singleton: (key,value) -- (name,pointer)

     vector<releaseFun> m_vSingletonReleaseFun;              //store the destructor of singleton

};

extern AppInstance* GetAppInstance();

#endif

这样你就可以将Singleton 存到AppInstance 之中,在附件Singleton 之中,你会发现AppInstanceGetInstance 中使用了静态变量,这只是为了在控件台中模拟才这样的,在实际中你会有创建AppInstance 的时机的。

如果平台只支持类的静态变量,而不支持函数内的静态变量,我想大家都知道该存哪儿,我就不多唠叨了。

Singleton 的析构。

         在平台支持静态变量的时候,我们可以像下面一样优雅地搞扼这个问题 :

Singleton*    Singleton::GetInstance(void )

{

     static Singleton g_oInstance;

     return &g_oInstance;

}

    对于不支持在函数内定义静态变量的平台,我也在百度上搜得一极具创意的实现,如下:

#ifndef _SINGLETONCHEAT_H

#define _SINGLETONCHEAT_H

#include <iostream>

using std::cout;

using std::endl;

class Singleton

{

public :

     static Singleton* GetInstance()

     {

         if (0 == Singleton::g_pInstance)

         {

              Singleton::g_pInstance = new Singleton;

         }

         return Singleton::g_pInstance;

     }

     ~Singleton()

     {

         cout<<__FUNCTION__<<endl;

     }

private :

     Singleton()

     {

         cout<<__FUNCTION__<<endl;

     }

     class SingletonCollector

     {

     public:

         ~SingletonCollector()

         {

              delete Singleton::g_pInstance;

         }

     };

     static SingletonCollector collector;

     static Singleton* g_pInstance;

};

Singleton* Singleton::g_pInstance = NULL;

Singleton::SingletonCollector Singleton::collector = Singleton::SingletonCollector();

#endif

如果平台干脆不支持静态变量,解决办法就不那么优雅了,你说可能会说在AppInstance 中一个个地删除就行了啊,我完全同意,可是我们要小心:

1.  AppInstance 不知道每个Singleton ,直接delete 那个void* ,只相当于delete 了个int ,用户会抱怨内存用完了。

2.  如果你将Singleton 的头文件包含进来,那么就会引入那讨人厌的信赖,让你的维护成本一下子提高几倍。

有两种方案可以解决这个问题:

1.       让所有的 Singleton 从一个基类派 SingletonBase 生而来,将让这个基类的析构函数为虚,注册 Singleton 的时候传进的指针不再是 void* 而是 SingletonBase*

2.       为每个 Singleton 注册一个 release 函数到 AppInstance , 我就是这么干的。

实现

         解决掉上面的两个问题后, Singleton 的方便之门又为我们打开了。不过我是个懒人,不想每次写一个单例都要循规蹈矩地写一大堆代码,虽然我不喜欢宏,但是在这里它确实可以帮我,所以我就再破例使用一次 , 由于实现有差不多 100 行,大家自行参考 Singleton.zip 中的 SingletonDef.h ,其中,我定义了三个宏 :

1.       DECLARE_SINGLETON(Singleton) : 用于在定义类时申明它是一个 Singleton

2.       BEGIN_IMPLEMENT_SINGLETON(Singleton): 在实现类时开始实例化 Singleton ;

3.       END_IMPLEMENT_SINGLETON(Singleton) :结束 Singleton 的实例化。

现在,要写一个单例, 3 句话就搞定啦 , 看下面这个例子 ( 见附件中的 Singleton.zip):

//==================================file Singleton.h=============================================

#ifndef _SINGLETON_H

#define _SINGLETON_H

#include "SingletonDef.h"

class Singleton

{

     DECLARE_SINGLETON(Singleton);

     Singleton();      

public :

     ~Singleton();

public :

     void fun(void );

};

#endif

 

//==============================file Singleton.cpp==============================================================

#include "Singleton.h"

#include <iostream>

using std::cout;

using std::endl;

 

BEGIN_IMPLEMENT_SINGLETON(Singleton)

     Singleton();

END_IMPLEMENT_SINGLETON(Singleton)

 

Singleton::Singleton()

{

     cout<<__FUNCTION__<<endl;

}

 

Singleton::~Singleton()

{

     cout<<__FUNCTION__<<endl;

}

 

void Singleton::fun(void )

{

     cout<<__FUNCTION__<<endl;

}

 

最后要谢谢一下chengxiong兄,给我指出了一个白痴地错误

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值