子类继承父类的虚函数调用

父类:Father

子类:Son

1.  Father* fa=new Son()

    实例1:

#include
using namespace std;

class Father{
public:
	Father(){
		cout << "this is the Father constructor!" << endl;
	}
	void watchTv(){
		cout << "Father is watching tv!" << endl;
	}
	virtual void say(){
		cout << "Father is saying!" << endl;
	}
};

class Son :public Father{
public:
	Son(){
		cout << "this is the Son constructor!" << endl;
	}
	void watchTv(){
		cout << "Son is watching tv!" << endl;
	}
	void say(){
		cout << "Son is saying!" << endl;
	}
};

int main(){
	Father* fa = new Son();
	fa->watchTv();
	fa->say();
	system("pause");
	return 0;
}
运行结果:

子类继承父类的虚函数调用_第1张图片

结果分析:

1.首先运行代码 Father* fa=new Son();,会首先调用父类构造函数,再调用子类构造函数,所以第一、第二行如图所示;

2.运行代码fa->watchTv(),根据fa的类型,因为是Father类型的,所以会先查看Father类中的watchTv函数,因为不是虚函数,所以直接调用,结果如第三行所示;

3.运行代码fa->say(),根据fa的类型,因为是Father类型的,所以先查看Father类中的say函数,因为是虚函数,所以会查看虚函数表,查看实现实例,找到子类Son有实现虚函数say,所以会调用子类Son的say函数,结果如第四行所示。


  实例2: 在构造函数中调用虚函数

#include
#include
using namespace std;
class Father{
public:
	Father():val("HunanTv"){
		cout << "this is the Father constructor!" << endl;
		say();
	}
	virtual void watchTv(){
		cout << "Father is watching tv:" <say();
	system("pause");
	return 0;
}

运行结果:

子类继承父类的虚函数调用_第2张图片

结果分析:

1.运行代码Father* fa=new Son(),会先调用父类构造函数,父类构造函数中会执行以下操作:a)首先给变量val赋值为“HunanTv",其次,调用函数say(),此时会输出前两行内容;b)因为say()函数会调用虚函数watchTv(),而且在子类中有watchTv的实例实现,但是根据输出结果第三行发现,调用的还是父类的虚函数,为什么呢?因为,父类构造函数中调用虚函数,表现的虚函数为父类的虚函数,所以结果为第三行的显示;c)父类构造函数调用完后,执行子类构造函数,因为子类没有定义say()函数,所以调用继承自父类的say()函数,所以输出结果为第四、第五行;d)say函数调用虚函数watchTv(),因为是在子类Son的构造函数中调用虚函数,所以调用的是子类的watchTv,所以输出结果如第六行所示;e)执行完子类构建后,执行fa->say();,首先看fa的类型,所以调用父类的say(),say()调用虚函数watchTv时,因为watchTv在子类中有实例实现,所以会调用子类的watchTv,所以输出结果如第七、第八行所示。


总结:

1.当在构造函数中调用虚函数时,虚函数表现为该类中虚函数的行为,即父类构造函数调用虚函数,则虚函数为父类中的虚函数;子类构造函数中调用虚函数,则调用的是子类中的虚函数;

2.如果不是在构造函数中调用虚函数,则会首先查看虚函数表,如果有实例实现,则调用实例。比如:父类中有虚函数watchTv,则调用父类中watchTv时,则因为子类实现了watchTv,则调用子类的watchTv。


你可能感兴趣的:(C++)