• C/C++ 多继承{虚基类,虚继承,构造顺序,析构顺序}


    C/C++:一个基类继承和多个基类继承的区别

    1.对多个基类继承会出现类之间嵌套时出现的同名问题,如果同名变量或者函数出现不在同一层次,则底层派生隐藏外层比如继承基类的同名变量和函数,不会出现二义性,而如果出现在同一阶层, 则会 出现二义性,解决办法:要么在同一阶层的底层(派生类)中重新定义可以解决,或者使用虚基类(减少部分二义性)

    2.虚基类:在派生列表中使用virtual关键字的基类(即使这部分虚基类在继承中多次出现,但只初始化一份)  虚继承:虚基类将被 "最底层派生类"(任何虚基类以下派生类都可能是最底层派生类,所以都应该提供虚基类的初始值(即构造虚基类))初始化,因此最底层派生类应该含有它所有虚基类的初始值(即构造虚基类)

    3.虚基类保证多次继承相同基类但只有一份基类数据(保证共享);

    4.虚继承的构造顺序由编译器按照派生类列表从左往右寻找直接继承的虚基类/间接继承的虚基类,先构造虚基类部分,然后按照正常构造从左到右构造,最后构造本身,而析构相反

    5.派生类的合成拷贝和构造,赋值都是按照上述规则执行,所以手动写拷贝,构造,和赋值时,需要按照这个顺序构造

    6.所以虚继承出现在虚基类之后(个人理解)

    C/C++代码:

     1 #include <cstdlib>
     2 #include <iostream>
     3 
     4 class Class
     5 {
     6 };
     7 
     8 class Base : public Class
     9 {
    10 protected:
    11     int value;
    12 public:
    13     Base() : value(0)
    14     {};
    15 
    16     Base(const Base &rhs) : Class(), value(rhs.value)
    17     {};
    18 
    19     Base(int a) : value(a), Class()
    20     {};
    21 };
    22 
    23 
    24 class D1 : virtual public Base
    25 {
    26 public:
    27     D1() : Base()
    28     {};
    29 
    30     D1(int a) : Base(a)
    31     {};
    32 
    33     D1(const D1 &rhs) : Base(rhs)
    34     {};
    35 };
    36 
    37 class D2 : virtual public Base
    38 {
    39 public:
    40     D2() : Base()
    41     {};
    42 
    43     D2(int a) : Base(a)
    44     {};
    45 
    46     D2(const D2 &rhs) : Base(rhs)
    47     {};
    48 };
    49 
    50 
    51 class MI : public D1, public D2
    52 {
    53 public:
    54     MI() : D1(), D2()
    55     {}
    56 
    57     MI(int a) : Base(a), D1(a), D2(a)
    58     {};
    59 
    60     MI(const MI &rhs) : Base(rhs), D1(rhs), D2(rhs)
    61     {};
    62 };
    63 
    64 class Final : public MI, public Class
    65 {
    66 public:  
    67     using Base::value;     //using 可改变继承变量权限
    68 
    69     Final()
    70     {};
    71 
    72     Final(int a) : Base(a), MI(a), Class()       //可通过不写Base(a),输出value查看,value是否被赋值
    73     {};
    74 
    75     Final(const Final &rhs) : Base(rhs), MI(rhs), Class()
    76     {};
    77 
    78 };
    79 
    80 
    81 int main()
    82 {
    83     Final A(20);
    84     std::cout << A.value << std::endl;
    85     return 0;
    86 }

             

  • 相关阅读:
    Win11安装跳过TPM的方法 Win11安装怎么跳过TPM
    选取文件,列举文件(含子文件夹),记录大小信息,限制文件层级
    选取文件夹,枚举文件及子文件夹
    数据库SQL中having和where的用法区别
    Environ 函数调用系统环境变量 电脑用户名等
    Notepad++正则表达式语法
    VB几种函数参数传递方法,Variant,数组,Optional,ParamArray
    Access导出到Excel方法汇总
    VBA编程自动导出生成Excel表
    LeetCode 136 只出现一次的数字
  • 原文地址:https://www.cnblogs.com/xuaidongstdudyrecording/p/7241411.html
Copyright © 2020-2023  润新知