以前是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