关于友元和单利模式
再次发帖讨论单例模式在c++中的实现
以下是一个博客里的文章
http://www.cnblogs.com/baiyanhuang/archive/2009/09/16/1730741.html
而C++中由于提供了友元这个特性,实现起来要好一些:
// Singleton base class, each class need to be a singleton should
// derived from this class
template <class T> class Singleton
{
protected:
Singleton(){}
public:
static T& Instance()
{
static T instance;
return instance;
}
};
// Concrete singleton class, derived from Singleton<T>
class ExampleSingleton: public Singleton<ExampleSingleton>
{
// so that Singleton<ExampleSingleton> can access the
// protected constructor
friend class Singleton<ExampleSingleton>;
protected:
ExampleSingleton(){}
public:
// This class's real functionalities
void Write(){printf("Hello, World!");}
};
// use this singleton class
ExampleSingleton::Instance().Write();
在C++友元的帮助下,我们成功实现了在编译期保证实例的唯一性。(当然,前提是你不要"乱交朋友")。
有人可能会问,实现singleton的代码并不多,我们没必要搞这么一个机制来做代码复用吧? 的确,我们复用的代码并不是很多,但是,我想代码复用的目的不仅仅是减少代码量,其最重要的目的还是在于保持行为的一致性,以便于使用与维护。(用函数替换代码段便是一个很好的例子)。
对于这里的singleton类来讲,如果不做这个设计,我们在每个具体的singleton类内部实现其singleton机制,那么可能出现的问题是
1. 很难保证其接口的一致性
张三写了一个singleton类,全局访问函数是Instance, 李四也写了一个Singleton类,全局访问函数可能就是GetInstance了。。。。。我们并没有一个健壮的机制来保证接口的一致性,从而导致了使用的混乱性。
2. 不易维护
Singleton创建实例有两种:一种为lazy initialization, 一种就是early initialization, 假如开始的实现是所有的singleton都用lazy initialization, 突然某种需求要求你用early initialization,你的噩梦就开始了,你不得不重写每一个singleton类。
而用了singleton模板基类这种机制,以上问题就不会存在,我们得到的不仅仅是节约几行代码:)
问题1:
这里用了奇异递归模式, 我的问题是:奇异递归在这里有什么意义吗? 难道是作者无意的写法,导致我想多了?
问题2: 父类难道也要 作为友元,才能访问 派生类的构造函数吗?
问题3:
关于lazy 和early的问题, 对于以上的例子的写法,属于哪一种模式,为什么?我实在搞不清,
问题有些多,谢谢大家。
以下是一个博客里的文章
http://www.cnblogs.com/baiyanhuang/archive/2009/09/16/1730741.html
而C++中由于提供了友元这个特性,实现起来要好一些:
// Singleton base class, each class need to be a singleton should
// derived from this class
template <class T> class Singleton
{
protected:
Singleton(){}
public:
static T& Instance()
{
static T instance;
return instance;
}
};
// Concrete singleton class, derived from Singleton<T>
class ExampleSingleton: public Singleton<ExampleSingleton>
{
// so that Singleton<ExampleSingleton> can access the
// protected constructor
friend class Singleton<ExampleSingleton>;
protected:
ExampleSingleton(){}
public:
// This class's real functionalities
void Write(){printf("Hello, World!");}
};
// use this singleton class
ExampleSingleton::Instance().Write();
在C++友元的帮助下,我们成功实现了在编译期保证实例的唯一性。(当然,前提是你不要"乱交朋友")。
有人可能会问,实现singleton的代码并不多,我们没必要搞这么一个机制来做代码复用吧? 的确,我们复用的代码并不是很多,但是,我想代码复用的目的不仅仅是减少代码量,其最重要的目的还是在于保持行为的一致性,以便于使用与维护。(用函数替换代码段便是一个很好的例子)。
对于这里的singleton类来讲,如果不做这个设计,我们在每个具体的singleton类内部实现其singleton机制,那么可能出现的问题是
1. 很难保证其接口的一致性
张三写了一个singleton类,全局访问函数是Instance, 李四也写了一个Singleton类,全局访问函数可能就是GetInstance了。。。。。我们并没有一个健壮的机制来保证接口的一致性,从而导致了使用的混乱性。
2. 不易维护
Singleton创建实例有两种:一种为lazy initialization, 一种就是early initialization, 假如开始的实现是所有的singleton都用lazy initialization, 突然某种需求要求你用early initialization,你的噩梦就开始了,你不得不重写每一个singleton类。
而用了singleton模板基类这种机制,以上问题就不会存在,我们得到的不仅仅是节约几行代码:)
问题1:
这里用了奇异递归模式, 我的问题是:奇异递归在这里有什么意义吗? 难道是作者无意的写法,导致我想多了?
问题2: 父类难道也要 作为友元,才能访问 派生类的构造函数吗?
问题3:
关于lazy 和early的问题, 对于以上的例子的写法,属于哪一种模式,为什么?我实在搞不清,
问题有些多,谢谢大家。
...全文


