C++函数查找的一般性规律(二)
来源:互联网 发布:足球彩票分析软件 编辑:程序博客网 时间:2024/05/16 05:40
上一篇文章中对重载函数的函数查找规律进行说明,这篇文章将会对重写情况进行说明,重写发生
在类的继承过程中,今天将说明重写的函数调用过程
我们有如下假定:函数调用以p->func()或p.func()的形式调用,则主要分为如下四个步骤:
1)首先确定p的静态类型,只有静态类型是类类型,那么我们才能调用成员,并且静态类型决定了哪些成员是可见的。
2)在p对应的静态类型对应的类中查找func。如果找不到,则一次在直接基类中查找直到到达继承链的顶端。若仍然找
不到名为func的函数,则编译器将报错。这一步可以认为是重载中的候选函数的确定。
3)一旦找到了func,就进行常规的类型检查以确认本次找到的func,对于本次调用是否合法。这一步可以看作是重载中
后两步的集合。
4)假设第三步中调用合法,那么编译器蒋根据调用的是否时虚函数而产生不同的代码:
1>如果func是虚函数并且我们是通过应用或者指针进行的调用,则编译器产生的代码将在运行是确定到底运行该虚函
数的哪个版本(基类还是派生类),选择的依据是动态类型。
2>如果func不是虚函数,或者我们是通过对象进行的调用,则编译器将会产生一个常规函数调用的代码,即根据静态
类型进行函数调用。
类定义如下:
class Parent{public: Parent () {cout<<"Parent"<<endl;}~ Parent () {cout<<"~Parent"<<endl;}virtual void vDis(){cout<<"Parent::virtual void vDis()"<<endl;}};class Child:public Parent{public:Child(){cout<<"Child"<<endl;}~Child(){cout<<"~Child"<<endl;}void vDis(){cout<<"Child::void vDis()"<<endl;}};
考虑如下代码:
int main(){Child c1;Parent *p1=&c1;p1->vDis();c1.vDis();return 0;}
输出结果如下:
Parent
Child
Child::voidvDis()
Child::voidvDis()
~Child
~Parent
结果分析:
在进行p1->vDis();函数调用时首先确定p1的静态类型即Parent类,然后在Parent类中查找vDis(),发现刚好有这个函数,
然后进行第三部发现调用合法,重点在第四步,此时vDis是虚函数,并且vDis是通过指针p1进行调用,所以要在运行
是确定到底调用哪个版本,依据是动态类型,p1的动态类型是Child类型,因此调用Child版本的vDis函数。
而c1.vDis();的前三步和前一个相同,我们分析第四步,此时vDis是虚函数,但是我们是通过对象调用,因此会根据静
态类型调用,即调用Child的vDis函数。
以上是我关于重写函数匹配的一点理解,若有错误,请批评指正,谢谢。
- C++函数查找的一般性规律(二)
- C++函数查找的一般性规律(一)
- 生成一般性规律的序列
- Web App 页面构建的一般性规律
- 折半查找的函数实现(C++)
- 二叉查找树的C语言实现(二)
- 利用cnComm的串口一般性用法之二
- Jlinkv8的一般性修复(刷固件)
- c实现的字符串查找函数
- C语言的字符串查找函数
- [C++]string类的查找函数
- 兔子的烦恼(二) nyoj (规律)
- (二) E - E && hdoj 无限的路 【规律】
- HPU 1006: 机房的位置(二)【规律】
- java的一般性指导
- pppoe设计的一般性
- 一般性问题的解决方法
- 解决问题的一般性步骤
- 内部类实现一个接口与外围类实现这个接口的区别
- 在ubuntu终端使用man
- 2016.8.15上午纪中初中部NOIP普及组比赛
- SAP FTP 相关
- 排序算法之归并排序(模板类)
- C++函数查找的一般性规律(二)
- printf格式总结
- 聊天机器人构建学习笔记-1
- 冒泡排序(Bubble Sort)
- iOS开发:网络监测
- 用XShell进行SSH连接Linux系统失败解决方法
- 新增商品
- Java开发环境搭建
- lightoj 1245 - Harmonic Number (II) (数学思维规律)