单例模式-基类单例。。用于其他单例的派生

来源:互联网 发布:西安金象网络 编辑:程序博客网 时间:2024/05/21 07:37


首先是继承方式,为了进行单例的派生,需要将基类的构造函数以及拷贝赋值函数设置为protected成员

template <class T>class Singleton{private:static T* m_Instance;protected:Singleton(){};Singleton(const Singleton &);Singleton &operator=(const Singleton &);public:static T* Get_Instance();static void Free_Instance();}


继续记录之前 需要了解一下C++的继承机制

注意:派生类访问说明符对于派生类的成员以及友元能否访问其直接基类的成员没什么影响。对于基类的成员的访问权限只与基类中的访问说明符有关。派生访问说明符的目的是控制派生类用户(包括派生类的派生类在内)对于基类成员的访问权限                      C++ primer 544页

以及友元类的机制

友元类可以通过自己的方法来访问把它当做朋友的那个类的所有成员。我们把类B设置成了类A的友元类,但是这并不会是类A成为类B的友元。说白了就是:甲愿意把甲的秘密告诉乙,但是乙不见得愿意把乙自己的秘密告诉甲。

#include "Father.h" class A{   friend class B; //友元类直接这样定义就OKpublic:   A(){ }; 

1)在A类中,将B类定义成友元
2)写一个C类继承自B类
3)在B类和C类的构造函数中分别创建A对象,并定义其内部的三个变量
4)在A类的构造函数中创建B对象,并定义其内部的三个变量

结果及注意事项:

1)B类中创建的A对象允许直接访问A类中所有变量
2)C类中创建的A对象只允许直接访问A类中Public变量
3)由第二点可知,友元关系无法继承
4)A类中创建的B对象只允许直接访问B类中的Public变量
5)由第四点可知,友元关系是单向的,即A为B友元,B并不是A的友元,需要另外单独定义

注意:A类中定义 B类为友元,则B类中可以使用A中所有的变量

http://www.cnblogs.com/dyllove98/archive/2013/07/12/3186943.html


基础都忘记了,复习了一遍后继续来单例

有了单例的基类后,接下来就是继承使用它了。于是乎,自定义一个类test继承自基类,此时需要注意继承的方式,public,private,protected,由于需要在在使用时使用 test::Get_Instance()的方式,所以需要使用public来继承。

class test : public Singleton<test>{}
相信想我一样的C++新手绝对对这个东西一脸懵逼..................自己继承自自己的感觉......................

template<class T>
class A
{...}
class B:public A<B>
{...}
对于这样的形式,B类是如何构造的?  举个栗子 O(∩_∩)O~~:

template <class T>class A{private:T *t;public:A(){t = new T();}};class B : A<B>{private:int a;public:B(int a_=0):a(a_){}};
声明一个B b 必然会执行B的构造函数B(),由于B是继承而来的,所以要执行基类的构造函数,于是执行A(),在该例子中,A()中执行 t=new T(),于是又会执行B的构造函数B(),于是接着又是A()从而造成了死循环。。。所以可知,在A<B>的构造函数中不能出现对于B的生成操作,不然会死循环。

template <class T>class A{private:T *t;public:A(){}};class B : A<B>{private:int a;public:B(int a_=0):a(a_){}};
这样 B b就不会出现错误了。

由于是单例,所以需要构造函数为保护或者私有,可以写出

class test:Singleton<test>{private:test();public://do//do}

此时,使用test::Get_Instance()问题又出现了,首先调用test::Get_Instance(),然后调用Singleton类中的Get_Instance()函数,执行到new T()的时候跳转执行test类的构造函数test(),然后就像上述说的过程,压栈跳转执行Singleton类的构造函数Singleton(),执行完毕后跳回test(),然后在跳回到new T(),return t完成。 但是由于test类的构造函数为私有或者保护,无法执行new T(),为了能使得Get_Instance()函数所在的类能执行new T() ,所以需要将Singleton设置为test的友元函数,这样Singleton类就行使用test的所有成员。

所以整体为:

template <class T>class Singleton{private:static T* m_Instance;protected:Singleton(){};Singleton(const Singleton &);Singleton &operator=(const Singleton &);public:static T* Get_Instance();static void Free_Instance();}
class test: public Singleton<test>{friend class Singleton<test>;private:test(){}public://do}



1 0