前面讲到,派生类的构造函数和析构函数会自动调用基类的构造函数和析构函数,那么要让一个类不能被继承,那么就将它的构造函数和析构函数私有函数(派生类可以访问保护函数)。那么怎样才能得到该类的实例呢? 这倒不难,可以通过定义公有的静态函数来创建和释放类的实例,实现该类不能被继承但能被实例化的功能。
1 #include"stdafx.h" 2 #include<iostream> 3 using namespace std; 4 5 class Base 6 { 7 private: 8 Base(){}; 9 ~Base(){}; 10 public: 11 int num; 12 static Base* Construct() 13 { 14 return new Base; 15 } 16 static Base* Construct(int n) 17 { 18 Base *p=new Base; 19 p->num=n; 20 cout<<"num is:"<<p->num<<endl; 21 return p; 22 } 23 static void Destruct(Base* instance) 24 { 25 delete instance; 26 instance=NULL; 27 } 28 }; 29 30 int main() 31 { 32 Base *b1; 33 Base *b2=Base::Construct(9); 34 Base::Destruct(b2); 35 return 0; 36 }
这样的类只能在堆上构建一个对象,却不能够在栈上构建。
最好的方法是使用虚继承:
1 class Base; 2 3 class Friend 4 { 5 private: 6 Friend(){};
7 ~Friend(){};
8 public: 9 friend Base; 10 }; 11 12 class Base:virtual public Friend 13 { 14 public: 15 Base(){}; 16 ~Base(){}; 17 };
理论上,若某一类Derived继承自Base,那么它需要自动调用Base的构造函数,而Base继承自Friend,那么先要调用Friend的构造函数,Base是Friend的友元类,所以Base能够访问Base的私有构造函数。但是这里,Friend是虚基类,Base虚继承自Friend,对于虚基类(Friend)的任何一个直接或间接派生类(Derived)的构造函数,它们的初始化都必须包含对该虚基类构造函数的直接调用,以初始化虚基类中的数据成员。所以这里,Derived需要直接调用Base的私有构造函数,显然是不被允许的,所以Derived不能继承Base。
小小的一题包含了很多的重要的知识!
参考:
1.用C++实现一个不能被继承的类http://blog.163.com/xiangzaihui@126/blog/static/166955749201182295845689/
2.关于构造单实例类的一个问题http://www.vckbase.com/index.php/wv/368
3.其他