1 ```cpp
2
3
4 //============================================================================
5 // Name : TS.cpp
6 // Author : jiudianren
7 // Version :
8 // Copyright : Your copyright notice
9 // Description : Hello World in C++, Ansi-style
10 //============================================================================
11
12 #include <iostream>
13 #include <functional>
14
15 using namespace std;
16
17
18 class A
19 {
20 protected:
21 int m_data;
22 public:
23 A(int data = 0)
24 {
25 m_data = data;
26 }
27 int GetData()
28 {
29 return doGetData();
30 }
31 virtual int doGetData()
32 {
33 return m_data;
34 }
35 };
36
37
38
39 class B: public A
40 {
41 protected:
42 int m_data;
43 public:
44 B(int data = 1)
45 {
46 m_data = data;
47 }
48 int doGetData()
49 {
50 return m_data;
51 }
52 };
53
54
55 class C: public B
56 {
57 protected:
58 int m_data;
59 public:
60 C(int data = 2)
61 {
62 m_data = data;
63 }
64
65 int doGetData()
66 {
67 return m_data;
68 }
69 };
70
71 void ref(C* & d)
72 {
73 cout<<d->GetData()<<endl; //题1
74 cout<<d->A::GetData()<<endl; //题2
75 cout<<d->B::GetData()<<endl; //题3
76 cout<<d->C::GetData()<<endl; //题4
77
78 cout<<d->doGetData()<<endl; //题5
79 cout<<d->A::doGetData()<<endl; //题6
80 cout<<d->B::doGetData()<<endl; //题7
81 cout<<d->C::doGetData()<<endl; //题8
82 }
83 int main()
84 {
85 C c(10);
86 cout<<c.GetData()<<endl; //题1
87 cout<<c.A::GetData()<<endl; //题2
88 cout<<c.B::GetData()<<endl; //题3
89 cout<<c.C::GetData()<<endl; //题4
90
91 cout<<c.doGetData()<<endl; //题5
92 cout<<c.A::doGetData()<<endl; //题6
93 cout<<c.B::doGetData()<<endl; //题7
94 cout<<c.C::doGetData()<<endl; //题8
95
96 cout<<"sssssssssss"<<endl; //题8
97 C *f=new C(11);
98 C *d=f;
99 cout<<d->GetData()<<endl; //题1
100 cout<<d->A::GetData()<<endl; //题2
101 cout<<d->B::GetData()<<endl; //题3
102 cout<<d->C::GetData()<<endl; //题4
103
104 cout<<d->doGetData()<<endl; //题5
105 cout<<d->A::doGetData()<<endl; //题6
106 cout<<d->B::doGetData()<<endl; //题7
107 cout<<d->C::doGetData()<<endl; //题8
108
109 cout<<"sssssssssss"<<endl; //题8
110 ref(f);
111 return 0;
112 }
113
114
115 ```
理解C++中继承层次的关键在于理解如何确定函数调用。确定函数调用遵循以下四个步骤:
(1)首先确定进行函数调用的对象、引用或指针的静态类型。
(2)在该类中查找函数,如果找不到,就在直接基类中查找,如此循着类的继承链往上找,直到找到该函数或者查找完最后一个类。如果不能在类或其相关类中找到该名字,则调用是错误的。
(3)一旦找到了该名字,就进行常规类型检查,查看该函数调用是否合法。
(4)若函数调用合法,编译器就生成代码。如果函数是虚函数且通过引用或指针调用,则编译器生成代码以确定根据对象的动态类型运行哪个函数版本,否则,编译器生成代码直接调用函数。
题1----题8
构造函数从最上层的基类开始构造,各个类的同名变量没有形成覆盖,都是单独的变量。
题1:
静态类型为C类,故在C类中找GetData()函数,C类中没有GetData()函数,由步骤(2),在其直接基类B类中查找,B类中也没有,再在A类中找,在A类中找到,且常规类型检查无误,调用合法,运行之。在其函数体类调用的doGetData()是虚函数,但不是通过引用或指针调用,故没有动态绑定,则由静态类型决定调用哪一个版本的doGetData(),静态类型为C类,C类中没有doGetData(),在其基类B类中找,找到,运行之,返回的是B::m_data,其值为默认实参值1。故本行输出1。
其他题类似,答案为1,1,1,1,1,0,1,1。
原文链接: https://www.cnblogs.com/jiudianren/p/5657098.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/236724
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!