C++函数查找的一般性规律(二)

上一篇文章中对重载函数的函数查找规律进行说明,这篇文章将会对重写情况进行说明,重写发生

在类的继承过程中,今天将说明重写的函数调用过程

我们有如下假定:函数调用以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是虚函数,但是我们是通过对象调用,因此会根据静

态类型调用,即调用ChildvDis函数。


以上是我关于重写函数匹配的一点理解,若有错误,请批评指正,谢谢。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值