User Tools

Site Tools


tech:programming:singleton

为了C++而C++?

单件的概念出现在当一个类允许且仅允许创建一个实例的情形中,标准教科书式C++实现如下:

class  CSingleton
{
protected:
    CSingleton()  {}
private:
    static  CSingleton*  m_pInstance;
public:
    static  CSingleton*  GetInstance  ()
    {
        if  (m_pInstance  ==  0)
            m_pInstance  =  new  CSingleton;
        return  m_pInstance;
    }
};
CSingleton*  CSingleton::m_pInstance=0;

由于构造函数定义为protected,所以用户无法显式创建CSingleton的实例,只能调用静态函数CSingleton::GetInstance()来获取一个CSingleton指针,而该指针指向一个唯一的CSingleton实例。这样的实现可以强行阻止用户显式创建CSingleton实例。

但是,既然C++并非一种严格的OO语言,未必非要使用如此别扭的方式来实现单件,定义一个全部由静态成员函数和静态成员变量组成的类亦是可行的,甚至可以采用如下的方式,CSingleton对象仍旧可以被显式创建,只是需要在注释中说明:要求用户通过使用由GetInstance()方法获取的对象指针来调用成员函数。

class  CSingleton
{
private:
    static  CSingleton*  m_pInstance;  
public:
    CSingleton()  {}
    CSingleton*  GetInstance  ()
    {
        if  (m_pInstance  ==  0)
            m_pInstance  =  new  CSingleton;
        return  m_pInstance;
    }  
};
CSingleton*  CSingleton::m_pInstance=0;

想到这个问题是因为最近拿到的代码,在里面发现了不少似是而非的单件的痕迹,而实际上好多并非属于必须使用单件的情况,即使是,为何不使用一个完全由静态成员组成的无对象概念的类?不知道是不是为了C++而C++。

项目设计阶段就曾为使用C语言还是C++语言发生过争执,我是主张用C,因为从需求上讲,一个低层系统的组件,完全是可以用C来实现的,结果又是OO,似乎OO才是软件的不二法门,便还是用C++了。我很厌恶C++的类,它居然要求在头文件中暴露接口的实现部分,结果不得不为每一个实现接口的类写一个虚基类。 既然是private,为什么一定需要暴露到头文件中?

一个C描述的接口:

/* "md.h" */
 
int  mdIntf_Open();
void  mdIntf_Close();
int  mdIntf_DoSomething_A();
int  mdIntf_DoSomething_B();
...
/* "md.c" */
 
#include  "md.h"
#include  "internals.h"  /*  implementation  details  */
 
/*  implementation  details  */
int  mdIntf_Open()
{...}
void  mdIntf_Close()
{...}
int  mdIntf_DoSomething_A()
{...}
int  mdIntf_DoSomething_B()
{...}
...

同样用C++描述的接口:

/* "md.h" */
 
class  Imd
{
public:
    Imd()  {}
    virtual  ~Imd()  {}
    virtual  int  Open()  =  0;
    virtual  void  Close()  =  0;
    virtual  int  DoSomething_A()  =  0;
    virtual  int  DoSomething_B()  =  0;
    ...
};
/* "md.c" */
 
#include  "md.h"
#include  "internal.h"  /*  implementation  details  */
class  Cmd  :  public  Imd
{
public:
    Cmd();
    virtual  ~Cmd();
    virtual  int  Open();
    virtual  void  Close();
    virtual  int  DoSomething_A();
    virtual  int  DoSomething_B();
    ...
protected:
    ...  /*  implementation  details  */
};
 
/*  implementation  details  */
Cmd::Cmd()
{...}
Cmd::~Cmd()
{...}
Cmd::Open()
{...}
Cmd::Close()
{...}
Cmd::DoSomething_A()
{...}
Cmd::DoSomething_B()
{...}
...

不是说反对使用C++,只是犯不着为了C++而C++。

tech/programming/singleton.txt · Last modified: 2014/11/10 08:22 (external edit)