设计模式C++实现(1)Singleton

时间:2022-09-09 08:45:18

  以前是C程序员, 也会接触CSharp的WinForm编程, 对设计模式的CSharp实现有过一点点研究.

设计模式是一种可复用的思想, 和用什么语言实现无关, 这一点是不可争议的.

现在转做C++编程了, 发现在C++与CSharp或是Java的实现还是有一定的区别

最近买了一本<<设计模式>> --- 机械工业出版社 一本很不错的书, 双语版

 

 

Singleton

我先假设看这段文字的是已经知道什么是Singleton的人, 那么我们要讨论的是Singleton的C++实现细节.

 

书上给我的源码:

class Singleton
{
private:
 static Singleton *_instance;
protected:
 Singleton();
public:
 static Singleton *Instance();
};
Singleton *Singleton::_instance = NULL;
Singleton::Singleton(){};
Singleton *Singleton::Instance()
{
 if (NULL == _instance)
 {
  _instance = new Singleton;
 }
 return _instance;
};

细心的人可能会发现: 如果客户代码如下, 那么些Singleton就不再是Singleton了

Singleton *p = Singleton::Instance();

Singleton obj = *p;

p指向的对象与obj对象不是同一个对象,

原因是书中忽略了两个类的成员 Singleton & operator=(const Singleton&); 及Singleton(const Singleton&);

 

 

于是在网上找了一些实现, 大概如下:

class Singleton
{
private:
 static Singleton *_instance;
protected:
 Singleton();
private:
 Singleton(const Singleton&);          // a
 Singleton &operator=(const Singleton &instance); // b
public:
 static Singleton *Instance();
};

与上面代码不一样的是多了a与b两处, 呵呵, 这两个成员只要声明就行了, 不用去定义他们, 因为他们根本就用不到

现在看来这确实是一个Singlton 了.    上面的客户代码肯定通不过编译,

Singleton *p = Singleton::Instance();

Singleton obj = *p;  // 会提示不可调用private成员

 

**但是Instance()返回的是一个指针,  实际的Singleton对象可以还保存有业务数据,  万一客户来个delete怎么办, 我们可不敢保证客户程序不会有这样的动作.  不但业务数据会丢失, 而且, 一旦再一次调用Singleton::Instance()返回的可是一个所谓的野指针, 整个程序一定挂.   那么我们规定客户不可以delete并以文档的形式通告他们, 问题不就解决了吗? 但是又出现了新的问题, 如果客户没有delete, 那谁来delete, 如果人人都推卸责任, 那结果只能是内存丢失了

 

有网友提出解决办法是把类的static Singleton *_instance; 改成static Singleton _instance; 再小小改动一个Instance的实现

Singleton *Singleton::Instance()
{
    return &_instance;
};

另一种解决加法是干脆去掉static Singleton *_instance或static Singleton _instance; Instance()实现如下:

Singleton *Singleton::Instance()
{

    static Singleton instance;
    return &instance;
};

哈哈, 已经相当完美了.

个人觉得返回指针不如返回引用, 这样客户在使用对象时就不用判断指针是否为空了, 当然客户知道他不为空也无须去判断

但是使用指针而不先判断是不是又违反了您以前的编码风格

那就返回引用吧

最后定版如下:

class Singleton
{
protected:
 Singleton();
private:
 Singleton(const Singleton&);   // a
 Singleton &operator=(const Singleton &instance);     // b
public:
 static Singleton &Instance();
};
Singleton::Singleton(){};
Singleton &Singleton::Instance()
{
 static Singleton instance;
 return instance;
};

a, b两处只要声明, 无须实现

这样客户程序如下调用:

Singleton &instance = Singleton::Instance(); 

 

到此就是我对Singleton的一点思考, 如果有什么不对的地方还望指正

 

当然<<Effective C++>>还提供了友元的实现, 也很perfect