




全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C+调用成员函数的步骤一般为:(1) 首先确定函数调用的对象、引用或指针的静态类型。(2) 在该类中查找函数,如果找不到就在直接基类中找,如此循环直到查找到最上层基类。(3) 一旦找到了改名字就进行常规的参数类型检查。(4) 假定函数调用是合法的,编译器就生成代码。如果函数是虚函数且通过引用或指针调用,则编译器生成代码以确定对象的动态类型运行哪个函数版本。注意:名字查找发生在编译期(即使是虚函数调用),而且与参数检查是不同阶段。如:class Basepublic: void fun();class Derived:public Basepublic: void fun(int a);Derived d;d.fun();/调用出错,因为编译器首先找到的是Derived中的fun,所以不在查找,但是参数检查时发现类型不匹配。对于通过基类指针或引用调用虚函数,同样编译器要在基类中查找函数名称,假定找到了函数名称,编译器就检查实参与形参是否匹配。这就是为什么虚函数必须在基类和派生类中拥有同一原型了。名字冲突造成的覆盖问题原则:如果基类和派生类使用相同名字的成员函数,在派生类作用域中派生类成员将屏蔽基类成员,即使函数原型不同,基类成员也会被屏蔽。如:class Basepublic: virtual void fun() coutBase:fun()endl; ;class Derived1:public Basepublic: void fun(int a) /虽然不是虚函数,但也将Base中的虚函数fun()隐藏了 coutDerived1:fun(int)endl; /这里有继承自Base的虚函数fun;class Derived2:public Derived1public: void fun(int a) /隐藏了Derived1的fun(int) coutDerived2:fun(int)endl; void fun() /重写了Base的虚函数 coutDerived2:fun()fun(); /Base:fun() pb2-fun(); /Base:fun() pb3-fun(); /Derived2:fun()下面分析两个经典面试题。l 例1:class A protected: int m_data; public: A(int data = 0) m_data = data; int GetData() return doGetData(); virtual int doGetData() return m_data; ; class B: public A protected : int m_data; public: B(int data = 1) m_data = data; int doGetData() return m_data; ; class C : public B protected : int m_data; public : C(int data = 2) m_data = data; ; int _tmain(int argc, _TCHAR* argv) C c(10); coutc.GetData() endl; /1 coutc.A:GetData()endl; /1 coutc.B:GetData()endl; /1 coutc.C:GetData()endl; /1 coutc.doGetData()endl; /1 coutc.A:doGetData()endl; /0 coutc.B:doGetData()endl; /1 coutc.C:doGetData()doGetData(); 这里通过指针调用虚函数,会发生动态绑定。因为this指向的c(派生类对象),所以要调用C中的虚函数doGetData。那C中有没有这个函数呢?虽然直接没有,但是别忘了C中有继承自B中的虚函数表,也就是调用B中的这个doGetData。之后的c.B:GetData()、c.C:GetData()、c.A:GetData()其实都一样,因为B、C中都没有GetData,所以都是调用的A中的GetData。下面c.doGetData(),由于是通过对象c调用虚函数doGetData,所以不会发生动态绑定。和调用普通函数一样,首先在当前作用域查找doGetData,没有,然后向上在B中找到了,就会调用B中的doGetData(输出1). 至于c.B:doGetData()和c.C:doGetData()作用相同,因为在C中没哟doGetData()。l 例2class A protected: int m_data; public: A(int data = 0) m_data = data; int GetData() return doGetData(); int doGetData() return m_data; ; class B: public A protected : int m_data; public: B(int data = 1) m_data = data; int doGetData() return m_data; ; class C : public B protected : int m_data; public : C(int data = 2) m_data = data; ; int _tmain(int argc, _TCHAR* argv) C c(10); coutc.GetData() endl; /0 coutc.A:GetData()endl; /0 coutc.B:GetData()endl; /0 coutc.C:GetData()endl; /0 coutc.doGetData()endl; /1 coutc.A:doGetData()endl; /0 coutc.B:doGetData()endl; /1 coutc.C:doGetData()endl; /1 return 0; 分析:c.GetData(),编译器首先在C中找GetData,没有找到就像上层基类B中寻找,也没有找到,再向A中寻找,发现A中有GetData()则调用。所以c.GetData()是调用A中的GetData。而GetData中又调用doGetData,而doGetData由于不是虚函数,所以也不会发生动态绑定,调用GetData时this是指向A的指针,所以就会调用A中的doGetData(从A中开始查找doGetData的名字)。A:GetData()、B:GetData()、C:GetData()的作用相同,只是查找的起始范围不同(分别从A、B、C中开始),但由于B、C中没有GetData,最终都是调用的A中的。c.doGetData(),会先在C中查找doGe
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 物业承包合同下新增厨师补充协议范文8篇
- 压力真空罐安全培训流程课件
- 2025年区块链行业区块链技术应用前景与金融改革研究报告
- 2025年物联网行业物联网技术应用前景研究报告
- 2025年火箭航天行业商业化前景预测报告
- 2025年环保行业绿色环保产品市场前景研究报告
- 2025年虚拟现实行业VR技术与虚拟现实应用前景研究报告
- 商品车电器使用培训课件
- 商品混凝土安全技术培训课件
- 2025重庆建峰工业集团有限公司招聘77人笔试参考题库附带答案详解
- 股权代持协议(模板)8篇
- 《AI创意课件之设计》课件
- 医院会计笔试题目及答案
- 河南豫信电科所属公司招聘笔试题库2025
- GB/T 45345-2025金属及其他无机覆盖层工程用直流磁控溅射银镀层镀层附着力的测量
- 无人机教员聘用协议书
- 药物非临床研究质量管理规范
- 脑科生理病理图谱解读
- 全国青少年科技辅导员专业水平认证笔试考题
- (行业)常用表面处理工艺详解(行业讲座教学培训课件)
- 配电网安健环设施标准
评论
0/150
提交评论