现在的位置: 首页 > 综合 > 正文

C++学习笔记之继承层次中的函数调用。

2017年11月10日 ⁄ 综合 ⁄ 共 1266字 ⁄ 字号 评论关闭

不妨将继承层次中的函数调用按照调用方式分类:

一、直接通过对象调用:

1、调用非虚函数。众所周知,一个派生类对象(public继承)是有两部分组成的,基类对象部分和派生类自己的部分,如果用派生类对象调用某一非虚函数(假设该函数在基类中为public)nvfcn() , 则编译器首先在派生类部分中查找该函数名字:若找到,则进行类型检查,检查正确-->调用、不正确-->报错;若找不到,则到基类中查找。。以此类推。例如:

class BaseClass
{
public:
	BaseClass(){};
	~BaseClass(){};
	void nvfcn()
	{
		cout << "基类"<< endl;
	}
};
class DerivedClass : public BaseClass
{
public:
	DerivedClass(){}
	~DerivedClass(){};
	void nvfcn( )
	{
		cout << "派生类"<< endl;
	}
};
DerivedClass dc;
dc.nvfcn();//结果为 派生类
//若将派生类中的nvfcn()函数改为nvfcn(int  a) 则会报错

那么为什么会报错?不应该在基类中找得到么?因为派生类的作用域是在基类的作用域之内的(函数的参数列表不同,这样区分不同的函数。它们在编译后就自动变成两个不同的函数名,有两个不用的地址)派生类的函数已经将基类中的同名函数屏蔽掉了!

如果把派生类中的函数注释掉,则会调用基类的函数。
2、虚函数也是如此。

二、通过基类的指针或者引用调用:

1、调用虚函数。通过基类的引用或者指针调用虚成员,是动态绑定的,调用基类还是派生类的函数是运行时候确定的(根据对象的实际类型),不是根据指针或者引用的静态类型。(在程序运行前不知道,会调用那个方法,而到运行时通过运算程序,动态的算出被调用的地址)。

class BaseClass
{
public:
	BaseClass(){};
	~BaseClass(){};
	virtual void vfcn()
	{
		cout << "Base:" << endl;
	}
	void nvfcn()
	{
		cout << "基类"<< endl;
	}
};
class DerivedClass : public BaseClass
{
public:
	DerivedClass(){}
	~DerivedClass(){};
	void vfcn()
	{
		cout << "Derived : " << endl;
	}
	void nvfcn()
	{
		cout << "派生类"<< endl;
	}
};

	BaseClass bc;
	DerivedClass dc;
	BaseClass * bp = &dc;
	bp->vfcn();

结果为派生类

2、非虚函数。非虚函数总是在编译时根据调用该函数的对象、引用或指针的类型确定,无论运行时实际对象是什么类型的,调用该对象的非虚函数都将会调用基类中定义的版本

BaseClass bc;
DerivedClass dc;
BaseClass * bp = &dc;
bp->vfcn();
bp->nvfcn();//显示基类

(以上为菜鸟看书之后的小总结,不知对不对,热烈欢迎批评指正!!不胜感激)

抱歉!评论已关闭.