c++设计一个不能被继承的类,为什么必须是虚继承?原因分析

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

用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>{   //一定注意 必须是虚继承
public:
    B(){
        cout << "B" << endl;
    }
};

class C:public B{
public:
    C(){}     //继承时报错,无法通过编译
};


int main(){
    B b;      //B类无法被继承
    //C c;
    return 0;
}

类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类就不能被继承了。

----------------------------------------------------

吐槽一下:面试中被问到这个问题,虽然答出了实现方法,但是原理没回答上,于是回来之后查了一下

大家都说这属于“奇技淫巧”,哎,面试官就爱问这些 我也很无语啊


关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看