• 继承2


    在继承方面引进多继承机制 一个类继承多个父类或者多个父类派生一个子类

    子类会吸收父类所有的成员 在子类继承中不同类继承同名的成员不能直接使用名字 否则会早成不明确的问题

    通过类名::成员 表示出继承哪一个父类的成员变量或者成员函数

    多继承中子类调用父类构造和继承顺序有关 先继承的先调用后继承的后调用 重名结果是最后继承的结果

    调用析构顺序和调用继承顺序相反 

    菱形继承 A派生类B,C 类B,C共同派生类D

    虚继承 关键字virtual  在继承前加上关键字表示虚继承

    虚继承主要解决的就是 菱形问题

     头文件A.h

     1 #pragma once
     2 #include<iostream>
     3 using namespace std;
     4 class A
     5 {
     6 protected:
     7     int m_a;
     8     int arr[100];
     9 public:
    10     A();
    11     ~A();//在类中调用构造和析构必须写名调用不然会包错 不写的花编译器会自动帮你生成一个构造和析构
    12 };
    13 class B : virtual public A
    14 {
    15 protected:
    16     int m_b;
    17     int x;
    18 public:
    19     B(){}
    20     ~B(){}
    21 };
    22 class C :virtual public A
    23 {
    24 protected:
    25         int m_c;
    26         int x;
    27 public:
    28     C(){}
    29     ~C(){}
    30 
    31         
    32 };
    33 class D : public B,public C//类D继承类BC
    34 {
    35 protected:
    36     int m_d;
    37 public:
    38     D(){}
    39     ~D(){}
    40     void fun(){
    41         m_b = 3;//继承B中的成员
    42         m_c = 2;//继承C中的成员
    43         B::x = 2;
    44         C::x = 4;//修改B中和C中的x的值
    45         //不能写x=2;这种方法无法确定调用的哪一个x
    46     }
    47 };
    48 
    49 class plant
    50 {
    51 protected:
    52     int color;
    53 public:
    54     plant(){
    55         cout << "调用plant构造" << endl;
    56         color = 3;
    57     }
    58     void printColor(){//在父类中输出color的值
    59         cout << color << endl;
    60     }
    61 
    62 };
    63 
    64 class fruit :virtual public plant
    65 {
    66 public:
    67     fruit()
    68     {
    69         cout << "调用fruit构造" << endl;//输出文字检测判定的顺序
    70         color = 2;//继承父类plant中的color成员
    71     }
    72 };
    73 class vegetable :virtual public plant
    74 {
    75 public:
    76     vegetable(){
    77         cout << "调用vegetable构造" << endl;
    78         color = 0;
    79     }
    80 
    81 };//类和结构体结尾都是以分号结束
    82 class tomato :public vegetable, public fruit//有先后顺序 先继承的先调用
    83 {
    84 public:
    85     void fun()
    86     {
    87         //color = 1;
    88         cout << "调用tomato下的fun函数" << endl;
    89     }
    90     void printColor()
    91     {
    92         cout << color << endl << vegetable::color << endl << fruit::color << endl;
    93     //不能直接写color要用域名解析符调用你所需要的哪个变量不然会造成语义不明确
    94         //利用虚函数可以对color直接调用因为color是祖父类的color
    95     }
    96 };

    对A的构造和析构进行声明

    #include "A.h"
    
    
    A::A()
    {
    }
    
    
    A::~A()
    {
    }
    

      主函数对类的调用

     1 #include "A.h"
     2 int main()
     3 {
     4     D d;
     5     cout << "D的大小" << sizeof(d) << endl;//没有使用虚继承的形式继承多少加多少 D的大小为103*2*4+4=828 
     6     //使用虚继承 偏移量4个字节 A:101*4+4 B:8+4 C:8 D:4 432
     7     tomato to;
     8     to.printColor();//输出结果调用color最后一次调用的是fruit所以三次结果都是2
     9     cout << "to的大小" << sizeof(to) << endl;//to是调用的color color是int为4个字节因为调用了三次所以为12个字节
    10     //去掉虚继承之后大小为8调用了两次color的值 
    11     cin.get();
    12     return 0;
    13 }
    14 
    15 //普通的多继承 子类继承多个父类的所有成员
    16 //子类调用构造的时候会一次调用多个父类的构造
    17 //子类对象包含所有父类的所有成员
    18 
    19 //虚继承
  • 相关阅读:
    linux 配置nginx+php-cgi
    有个故事
    2014短学期实习报告
    快速排序
    C++之共用体
    不能言传,等于不会
    java 动态绑定
    编程的理论深度
    Java 多客户端版 2048 源码
    热河看待苦难
  • 原文地址:https://www.cnblogs.com/liugangjiayou/p/11380920.html
Copyright © 2020-2023  润新知