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 }

             

  • 相关阅读:
    了解web前端基本常识
    解决移动端输入法挡住输入框的办法
    简单实现根据选项显示不同的表单
    关于“使用本服务器,放到正规的第三方服务器就不安全”的想法
    简单实现网页换肤功能
    Java项目引入eclipse注意事项
    hexo博客发布注意事项
    hexo博客出现“Cannot GET/xxxx”的错误
    C#中ToString()格式详解
    SQLSERVER 时间日期函数,查询今天日期、昨天、一个星期、半年前的数据
  • 原文地址:https://www.cnblogs.com/xuaidongstdudyrecording/p/7241411.html
Copyright © 2011-2022 走看看