• 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

  • 相关阅读:
    第十三周助教小结
    记事本
    第十二周助教小结
    与周老师会谈之后的感想
    第十一周总结
    第十周助教总结
    听周筠老师一席话,受益匪浅
    2020软件工程作业04
    2020软件工程作业02
    2020软件工程作业01
  • 原文地址:https://www.cnblogs.com/yanenquan/p/4006691.html
Copyright © 2020-2023  润新知