ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++继承深度解析

2022-06-14 23:34:05  阅读:149  来源: 互联网

标签:解析 Parent int 子类 mi C++ 深度 父类 public


一.继承的概念

继承是C++中代码复用的重要手段。通过继承,可以获得父类的所有功能,并且可以在子类中重写已有功能,或者添加新功能。

  1 #include <iostream>
  2 #include <string>
  3  
  4 using namespace std;
  5  
  6 class Memory
  7 {
  8 public:
  9     Memory()
 10     {
 11         cout << "Memory()" << endl;
 12     }
 13     ~Memory()
 14     {
 15         cout << "~Memory()" << endl;
 16     }
 17 };
 18  
 19 class Disk
 20 {
 21 public:
 22     Disk()
 23     {
 24         cout << "Disk()" << endl;
 25     }
 26     ~Disk()
 27     {
 28         cout << "~Disk()" << endl;
 29     }   
 30 };
 31  
 32 class CPU
 33 {
 34 public:
 35     CPU()
 36     {
 37         cout << "CPU()" << endl;
 38     }
 39     ~CPU()
 40     {
 41         cout << "~CPU()" << endl;
 42     }    
 43 };
 44  
 45 class MainBoard
 46 {
 47 public:
 48     MainBoard()
 49     {
 50         cout << "MainBoard()" << endl;
 51     }
 52     ~MainBoard()
 53     {
 54         cout << "~MainBoard()" << endl;
 55     }    
 56 };
 57  
 58 class Computer
 59 {
 60     Memory mMem;
 61     Disk mDisk;
 62     CPU mCPU;
 63     MainBoard mMainBoard;
 64 public:
 65     Computer()
 66     {
 67         cout << "Computer()" << endl;
 68     }
 69     void power()
 70     {
 71         cout << "power()" << endl;
 72     }
 73     void reset()
 74     {
 75         cout << "reset()" << endl;
 76     }
 77     ~Computer()
 78     {
 79         cout << "~Computer()" << endl;
 80     }
 81 };
 82  
 83 class HPBook : public Computer
 84 {
 85     string mOS;
 86 public:
 87     HPBook()
 88     {
 89         mOS = "Windows 8";
 90     }
 91     void install(string os)
 92     {
 93         mOS = os;
 94     }
 95     void OS()
 96     {
 97         cout << mOS << endl;
 98     }
 99 };
100  
101 class MacBook : public Computer
102 {
103 public:
104     void OS()
105     {
106         cout << "Mac OS" << endl;
107     }
108 };
109  
110 int main()
111 {   
112     HPBook hp;
113     
114     hp.power();  //子类调用power()
115     hp.install("Ubuntu 16.04 LTS");
116     hp.OS();
117     
118     cout << endl;
119     
120     MacBook mac;
121     
122     mac.OS();
123     
124     return 0;
125 }

结果:

 1 //HPBook类实例化过程
 2 Memory()      //先父母的成员变量
 3 Disk()
 4 CPU()
 5 MainBoard()
 6 Computer()    //父母的自身
 7 power()
 8 Ubuntu 16.04 LTS
 9 //MacBook类实例化过程
10 Memory()
11 Disk()
12 CPU()
13 MainBoard()
14 Computer()
15 Mac OS
16 ~Computer()
17 ~MainBoard()
18 ~CPU()
19 ~Disk()
20 ~Memory()
21 ~Computer()
22 ~MainBoard()
23 ~CPU()
24 ~Disk()
25 ~Memory()    

继承构造调用关系:先是调用父类的成员变量,然后再调用父类自身,再调用子类,析构的顺序则与构造的顺序相反。

二.继承中的访问级别

子类不能直接访问父类的私有成员private。

 1 #include <iostream>
 2 #include <string>
 3  
 4 using namespace std;
 5  
 6 class Parent
 7 {
 8 private:
 9     int mv;
10 public:
11     Parent()
12     {
13         mv = 100;
14     }
15     
16     int value()
17     {
18         return mv;
19     }
20 };
21  
22 class Child : public Parent
23 {
24 public:
25     int addValue(int v)
26     {
27         mv = mv + v;    // ???? 如何访问父类的非公有成员
28     }
29 };
30  
31 int main()
32 {   
33     return 0;
34 }

结果:编译错误

protected修饰的成员可以被子类及外界直接访问。

 1 #include <iostream>
 2 #include <string>
 3  
 4 using namespace std;
 5  
 6 class Parent
 7 {
 8 protected:
 9     int mv;
10 public:
11     Parent()
12     {
13         mv = 100;
14     }
15     
16     int value()
17     {
18         return mv;
19     }
20 };
21  
22 class Child : public Parent
23 {
24 public:
25     int addValue(int v)
26     {
27         mv = mv + v;    
28     }
29 };
30  
31 int main()
32 {   
33     Parent p;
34     
35     cout << "p.mv = " << p.value() << endl;  //100
36     
37     Child c;
38     
39     cout << "c.mv = " << c.value() << endl;    //100
40     
41     c.addValue(50);
42     
43     cout << "c.mv = " << c.value() << endl;    //150
44     
45     return 0;
46 }

用public修饰的的父类可以被子类及外界访问。用protected修饰的父类可以被子类访问,不能被外界访问。用private修饰的父类只能被父类的成员函数访问。

三.继承中子类与父类的同名成员变量,成员函数

通过作用域分辨符(::)访问父类中的同名成员

1 Child c;
2 c.mi = 100;           //子类中的mi
3 c.Parent::mi = 1000;  //父类中的mi
 1 #include <iostream>
 2 #include <string>
 3  
 4 using namespace std;
 5  
 6 class Parent
 7 {
 8 public:
 9     int mi;
10     
11     Parent()
12     {
13         cout << "Parent() : " << "&mi = " << &mi << endl;  
14     }   //确认成员变量地址,定位类Parent
15 };
16  
17 class Child : public Parent
18 {
19 public:
20     int mi;
21     
22     Child()
23     {
24         cout << "Child() : " << "&mi = " << &mi << endl;
25     }   //确认成员变量地址,定位类Child
26 };
27  
28 int main()
29 {
30     Child c;
31     
32     c.mi = 100;    
33     
34     c.Parent::mi = 1000;      //作用域分辨符,和命名空间有点像
35     
36     cout << "&c.mi = " << &c.mi << endl;  //查看是子类的
37     cout << "c.mi = " << c.mi << endl;
38     
39     cout << "&c.Parent::mi = " << &c.Parent::mi << endl;    //查看的是父类的
40     cout << "c.Parent::mi = " << c.Parent::mi << endl;
41     
42     return 0;
43 }

结果:

1 Parent() : &mi = 0xbfb99188
2 Child() : &mi = 0xbfb918c
3 &c.mi = 0xbfb9918c   //证明调用的子类mi
4 c.mi = 100     //打印子类中的mi
5 &c.Parent::mi = 0xbfb99188    //证明调用的子类继承自父类的mi
6 c.Parent::mi = 1000    //打印父类中的mi

当子类和父类有同名成员时,父类成员被子类覆盖,但是它依然存在子类中。

父类和子类之间的重载:

 1 #include <iostream>
 2 #include <string>
 3  
 4 using namespace std;
 5  
 6 class Parent
 7 {
 8 public:
 9     int mi;
10     
11     void add(int v)  //重载关系  
12     {
13         mi += v;
14     }
15     
16     void add(int a, int b)    //重载关系
17     {
18         mi += (a + b);
19     }
20 };
21  
22 class Child : public Parent
23 {
24 public:
25     int mi;
26     
27     void add(int x, int y, int z)
28     {
29         mi += (x + y + z);
30     }
31 };
32  
33 int main()
34 {
35     Child c;
36     
37     c.mi = 100;    //访问子类的mi
38     
39     c.Parent::mi = 1000;    //访问子类继承父类的mi
40     
41     cout << "c.mi = " << c.mi << endl;
42     
43     cout << "c.Parent::mi = " << c.Parent::mi << endl;
44     
45     c.Parent::add(1);        //解决方案
46     c.Parent::add(2, 3);
47     c.add(4, 5, 6);
48  
49     cout << "c.mi = " << c.mi << endl;
50     
51     cout << "c.Parent::mi = " << c.Parent::mi << endl;
52     
53     return 0;
54 }

结果:

1 c.mi = 100
2 c.Parent::mi = 1000    
3 c.mi = 115             //调用子类add(4, 5, 6)
4 c.Parent::mi = 1006    //调用父类add(1)和add(2,3)    

子类无法重载父类中的成员函数(作用域不同),使用作用域分辨符c.Parent::add访问父类中的同名函数。

子类和父类中的函数不能构成重载关系,子类可以定义父类中完全相同的成员函数。

四.多重继承可能产生冗余的成员

菱形继承:

 1 #include <iostream>
 2 #include <string>
 3  
 4 using namespace std;
 5  
 6 class People
 7 {
 8     string m_name;
 9     int m_age;
10 public:
11     People(string name, int age)
12     {
13         m_name = name;
14         m_age = age;
15     }
16     void print()
17     {
18         cout << "Name = " << m_name << ", "
19              << "Age = " << m_age << endl;
20     }
21 };
22  
23 class Teacher : public People
24 {
25 public:
26     Teacher(string name, int age) : People(name, age) //调用父类构造函数
27     {
28     }
29 };
30  
31 class Student : public People
32 {
33 public:
34     Student(string name, int age) : People(name, age)  //调用父类构造函数
35     {
36     }
37 };
38  
39 class Doctor : public Teacher, public Student
40 {
41 public:
42     Doctor(string name, int age) : Teacher(name, age), Student(name, age)
43     {
44     }
45 };
46  
47 int main()
48 {
49     Doctor d("Delphi", 33);
50     
51     d.print();
52     
53     return 0;
54 }

结果:编译出错

 

标签:解析,Parent,int,子类,mi,C++,深度,父类,public
来源: https://www.cnblogs.com/xiaogudexuexibiji/p/16376813.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有