以下是阿鲤对c++中多态的学习总结,希望可以帮助到大家
1:什么是多态?
2:多态的定义和实现
3:多态的原理
首先让我们看看什么是多态?
顾名思义,就是多种形态,具体点讲就是在完成某个行为的时候,不同的对象会产生不同的状态。
那么c++是怎样定义多态和实现的呢?
在c++中想要构成多态,需要满足以下两个条件:
1:调用函数的对象必须是指针或引用
2:被调用的函数必须是虚函数,且完成了虚函数的重写
举个栗子:
#include<iostream>
using namespace std;
class Person {
public:virtual void buy_ticket() {
cout << "买票全价" << endl;
}
};
class Student:public Person {
public:
virtual void buy_ticket() {
cout << "买票半价" << endl;
}
};
void func(Person &people) {
people.buy_ticket();
}
int main()
{
Person zhangsan;
func(zhangsan);
Student wangwu;
func(wangwu);
return 0;
}
看着上面这段代码,这就是c++中多态的简单实现;那么为什么呢?
1:这段代码在函数上加上了virtual,这就说明它满足了这是一个虚函数;
2:在派生类中,派生类有一个完全相同的虚函数,这就完成了虚函数的重写
3:在func函数中,我们是通过引用去调用函数的
ok,我们发现这段代码已经完成了c++的多态,那么怎样体现呢?
如果你运行这段代码,就会打印出
这就是c++中的多态;
ok,我们看到了多态的实现了,那c++多态的原理有是什么呢?
首先,我们打印一下这两个类答大小看看:
cout << sizeof(Person) << endl;
cout << sizeof(Student) << endl;
结果输出为:4 ,4 ;
我们都知道,空类的地址是1(用来表示这个类),而类中的函数是算在类的大小中的(存储在代码段,共享);
但是,通过我们的打印发现,带有虚函数的类的大小为4,那么这就说明了类中存储了某种东西,来帮助c++实现多态;
我们通过编译看看,发现在由这两个类实例化出的对象中含有_vfptr这么个东西;它叫做虚函数表指针;
这个虚函数表指针指向一个虚函数表;这个虚函数表里就存放着我们的虚函数指针;
而且观察仔细的同学就会发现在wangwu这个对象中,它的虚函数是存储在父类的虚函数表指针中的。但是虚函数已经被重写了。
总结&扩展:
1:c++的继承是通过虚函数表实现的
2:虚函数表只会存储虚函数,而且若被重写,派生类中就是重写后的虚函数
3:基类和派生类的虚函数表是不同的
4:虚函数指针,是类的一部分成员
5:派生类i中新添加的虚函数会放在虚函数表的后面
6:注意:虚表存储的是虚函数指针,而虚标是存储在代码段中的。
说了这么多,那么多态的原理到底是什么?
我们在看看这张图:
张三在调用时候,调用的是上面的函数,而王五在调用的时候就是下面的函数了;
并且这些函数调用都是在代码运行起来之后确定的,而不是在编译期间确定的。
补充一个概念:
静态绑定和动态绑定:
静态绑定:编译期间就确定了程序的行为;比如函数重载
动态绑定:是在程序运行期间,根据具体拿到的类型确定具体的行为;动态一定是动态绑定的。