zoukankan      html  css  js  c++  java
  • 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 }

             

  • 相关阅读:
    企业年金个税计算问题解读
    无线共享代码
    解决IE只能用管理员身份运行才能正常
    关于系统安装经验总结
    T-SQL 中Float数据类型的奇葩四舍五入
    win7 enterprise key backup
    IOS-触摸手势
    IOS-尺寸
    iOS开发-object-c之 @[], @{}
    IOS-电话和短信功能
  • 原文地址:https://www.cnblogs.com/xuaidongstdudyrecording/p/7241411.html
Copyright © 2011-2022 走看看