继承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 //虚继承

 

posted @ 2019-08-20 13:12  insist钢  阅读(265)  评论(0编辑  收藏  举报