C++多态与多态原理以及虚函数表
1. 多态2. 多态原理3. 重载和重写(覆盖)的区别
1. 多态
多态分为两类:静态多态(编译时多态)和动态多态(运行时多态) 静态多态就是我们所熟悉的函数重载和运算符重载,而派生类和虚函数实现动态多态。 静态多态和动态多态的区别就是函数地址是早绑定(静态联编)还是晚绑定(动态联编)。如果函数的调用,在编译阶段就可以确定函数的调用地址,并产生代码,就是静态多态(编译时多态),就是说地址是早绑定的。而如果函数的调用地址不能编译不能在编译期间确定,而需要在运行时才能决定,这这就属于晚绑定(动态多态,运行时多态)。
#include
using namespace std;
class Father{
public:
void Func(){
cout
cout
Father f;
f.Func();//自身成员函数调用
doFunc(f);//自身成员函数调用
cout
//void Func(){
cout
cout
Father f;
f.Func();//自身成员函数调用
doFunc(f);//自身成员函数调用
cout
cout
public:
virtual void speak(){
cout //Animal & animal = cat
animal.speak();
}
//如果发生了继承的关系,编译器允许进行类型转换
void test01(){
Cat cat;
doSpeak(cat);
}
int main(){
test01();
return EXIT_SUCCESS;
}
运行结果:
小猫在说话
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200530205009359.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDcxODc5NA==,size_16,color_FFFFFF,t_70)
当父类声明了虚函数之后,会在类内产生一个vfptr指针,指向其虚函数表,虚函数表内容为&Animal::speak在Cat类创建对象的时候,调用构造函数,会将其所有的vfptr都指向自己的虚函数表,表内容为&Cat::speak,这一步,子类写speak父类的虚函数,这种写法叫做重写(override),又叫做覆盖这样正在执行时,Animal* animal = new Cat; animal.speak();程序就会直接调用虚函数表里的内容
3. 重载和重写(覆盖)的区别
No.重载重写(覆盖)1重载要求函数名相同,但是参数列表必须不同,返回值可以相同也可以不同。覆盖要求函数名、参数列表、返回值必须相同。2在类中重载是同一个类中不同成员函数之间的关系。在类中覆盖则是子类和基类之间不同成员函数之间的关系。3重载函数的调用是根据参数列表决定。覆盖函数的调用是根据对象类型决定。4重载函数是在编译时确定调用一个函数。覆盖函数是在执行时确定调用个函数。
|