c++设计一个不能被继承的类

摘要:使用友元、私有构造函数、虚继承等方式可以使一个类不能被继承,可是为什么必须是虚继承?背后的原理又是什么?

用C++实现一个不能被继承的类(例1)

 1 #include <iostream>
 2 using namespace std;
 3
 4 template <typename T>
 5 class Base{
 6     friend T;
 7 private:
 8     Base(){
 9         cout << "base" << endl;
10     }
11     ~Base(){}
12 };
13
14 class B:virtual public Base<B>{   //一定注意 必须是虚继承
15 public:
16     B(){
17         cout << "B" << endl;
18     }
19 };
20
21 class C:public B{
22 public:
23     C(){}     //继承时报错,无法通过编译
24 };
25
26
27 int main(){
28     B b;      //B类无法被继承
29     //C c;
30     return 0;
31 }

类Base的构造函数和析构函数因为是私有的,只有Base类的友元可以访问,B类在继承时将模板的参数设置为了B类,所以构造B类对象时们可以直接访问父类(Base)的构造函数。

为什么必须是虚继承(virtual)呢?

参见 c++Primer 4th 第17.3.7节 特殊的初始化语义

通常每个类只初始化自己的直接基类,但是在虚继承的时候这个情况发生了变化,可能导致虚基类被多次初始化,这显然不是我们想要的。(例2: AA,AB都是类A的派生类,然后类C又继承自AA和AB,如果按之前的方法会导致C里面A被初始化两次,也会存在两份数据)

为了解决重复初始化的问题,从具有虚基类的类继承的类在初始化时进行了特殊处理,在虚派生中,由最低层次的派生类的构造函数初始化虚基类。在我们上面的例1中就是由C的构造函数控制如何进行虚基类的初始化。

为什么B类不能被继承?

回到例1,因为B是Base的友元,所以B对象可以正常创建,但由于B使用了虚继承,所以如果要创建C对象,那么C类的构造函数就要负责虚基类(Base)的构造,但是Base的构造函数是私有的,C没有访问的权限(ps:友元关系不能被继承的),所以例1中的C类在编译时就会报错。这样B类就不能被继承了。

转自:http://my.oschina.net/cuilili/blog/323696

时间: 2024-10-13 22:35:49

c++设计一个不能被继承的类的相关文章

c++设计一个不能被继承的类,原因分析

用C++实现一个不能被继承的类(例1) #include <iostream> using namespace std; template <typename T> class Base{     friend T; private:     Base(){         cout << "base" << endl;     }     ~Base(){} }; class B:virtual public Base<B>

用C++设计一个不能被继承的类(转)

在Java 中定义了关键字final,被final修饰的类不能被继承. 首先想到的是在C++中,子类的构造函数会自动调用父类的构造函数.同样,子类的析构函数也会自动调用父类的析构函数.要想一个类不能被继承,只要把它的构造函数和析构函数都定义为私有函数.那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数.析构函数而导致编译错误. 可是这个类的构造函数和析构函数都是私有函数了,怎样才能得到该类的实例呢?可以通过定义静态来创建和释放类的实例.基于这个思路,可以写出如下的代码: 1 /////

用C++ 设计一个不能被继承的类

http://blog.sina.com.cn/s/blog_69d9bff30100odlz.html 在Java 中定义了关键字final ,被final 修饰的类不能被继承.但在C++ 中没有final 这个关键字,要实现这个要求还是需要花费一些精力. 首先想到的是在C++ 中,子类的构造函数会自动调用父类的构造函数.同样,子类的析构函数也会自动调用父类的析构函数.要想一个类不能被继承,我们只要把它的构造函数和析构函 数都定义为私有函数.那么当一个类试图从它那继承的时候,必然会由于试图调用

用C++实现一个不能被继承的类

一道笔试题的思考: 记得,找工作时,遇到了这样的一道笔试题.记不清是那个公司的笔试题,反正觉得自己当时还真费了一点功夫的,但是也就搞定了一部分,结果还是被另一部分给鄙视啦! 现在静下来分析实现如下: 题目:用C++设计一个不能被继承的类 不能被继承?不能被继承?不能被继承?按照继承的理论知识分析,我们只要把类的构造函数设置为私有的,即可解决问题. 因为那样的话,子类就没有办法访问基类的构造函数,从而就阻止了进行子类构造对象的任务实现,也就达到了不可继承的目的. 但是,假设那样,这个类我们在其它地

C++设计实现一个不能被继承的类

C++不同于Java,Java中被final关键字修饰的类不能被继承,C++能实现不被继承的类,但是需要自己实现. 为了使类不被继承,最好的办法是使子类不能构造父类的部分,此时子类就无法实例化整个子类.在C++中,子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动的调用父类的析构函数,所以只要把类的构造函数和析构函数都定义为private()函数,那么当一个类试图从他那儿继承时,必然会由于试图调用构造函数.析构函数而导致编译错误.此时该类即不能被继承. 但由此会造成一个问题,priv

C++之如何实现一个不能被继承的类

C++中如何实现一个不能被继承的类? 在C#中可以使用sealed,Java中可以使用final来表示一个类不能被继承,而在c++中并没有这个,那我们怎么在c++中实现一个不能被继承的类呢? 1.把构造函数设为私有 这是最简单的一种办法了,那就是把构造函数设为私有,因为我们都知道当一个类试图从它那里继承的时候,必定会因为调用基类的构造函数,而基类的构造函数是私有的,这样会导致编译错误: 可是这样我们又怎么获得这个类的实例呢?我们可以定义公有的静态函数来获取和释放,有点类似单例模式~ class

剑指offer (48) c++实现一个不能被继承的类

题目:用c++实现一个不能被继承的类 题解分析: 常规解法: 首先想到的是在C++ 中,子类的构造函数会自动调用父类的构造函数.同样,子类的析构函数也会自动调用父类的析构函数. 要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数. 那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数.析构函数而导致编译错误. 可是这个类的构造函数和析构函数都是私有函数了,我们怎样才能得到该类的实例呢? 这难不倒我们,我们可以通过定义静态函数来创建和释放类的实例.基于这个思路,我们可以

如何产生一个不能被继承的类

对于这个问题,我首先想到的是将“父类”的构造函数声明为私有的,这样的话,子类就不能在自己的构造函数中调用父类的构造函数(就算没有显示调用父类的构造函数,编译器也会自动在子类的构造函数中插入调用父类构造函数的代码),于是就实现了不能被继承的类.同时,我们还是要能够产生这个类的对象,所有要公开一个方法,在该方法中调用私有构造函数.这种解法有点像Singleton. class CNoChildren{ public: CNoChildren* createCNoChildren(){ CNoChil

C++中定义一个不能被继承的类

1.一种错误的解法 最开始是从构造函数开始着手(先声明这种方法不能定义一个不能被继承的类,这是一种错误的方法,但是很容易往这方面想),假设存在下面的继承体系: 现在假设B是一个不能被继承的类,那么如果存在B的子类C,那么C的构造过程应该会报错,那么如何能够让B能正常构造而C不能正常构造呢?首先A,B,C的构造函数和析构函数都假设是public的,最开始想的是让B私有继承自A,根据private继承的特性,父类中public和protected的成员在子类中都会变成private的,那么A的构造函