多态的定义
多态就是通过引用或指针指向不同的对象,而调用相同名字的不同函数。
要注意,多态只针对共有继承。
我们需要对想要实现多态的函数使用virtual关键字修饰,将该函数声明为虚函数,在派生类中就可以重写该函数,实现多态。
重写函数,要求函数的返回值,函数名,参数列表完全相同。
虚函数周边
虚函数声明如下。
我们将存在纯虚函数的类称为抽象类,抽象类不能实例化出对象。
声明纯虚函数如下。
还存在两个虚函数的关键字,final,override。
final声明虚函数,则该虚函数不能被重写。
override声明虚函数, 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错。
析构函数重写意外
在多态这块,析构函数可能会析构不完全,这很可能导致内存泄露。
调用析构函数与对象的类型有关。
在多态调用中,派生类的析构函数没有被调用,为了解释这个问题,需要了解多态的原理,但为了解决这个问题,我们只需要重写派生类析构函数。
每个类的析构函数名字不同却能被重写,这是因为所有类的析构函数都会被解释destructor函数,这就满足了重写的条件。
多态的原理
多态调用可以通过指针或引用指向不同的对象从而调用两个类中的不同函数,实现多态的底层原理是虚函数表。
多态存在编译时多态,运行时多态。
1.编译时多态指重载,模板。
2.运行时多态指重写。重写虽然是运行时多态,但是虚函数表是在编译时生成的。
虚函数表详解
虚函数表存在内存中,而虚函数指针会被存在有虚函数的类中的第一个变量。
虚函数表指针存在对象的第一个位置,指向虚函数表。
在继承体系中,虚函数被重写后会在基类对象的虚函数表的函数被替换为派生类的函数。
之所以可以通过指针或引用指向不同对象,而调用不同的函数就是因为虚函数表中的函数被替换。
A对象指针/引用指向B对象,代表指针指向B对象模型中的A对象,而函数被重写后,虚函数表中的函数就被替换,所以才可以调用B对象的函数。
多继承中存在未重写的虚函数,则该虚函数会被放在第一个被继承的基类的虚函数表中。
多态的问题
(1).内联函数可以被声明为虚函数,虽然被inline声明的函数不会被符号表记录地址,但是inline具有两重性,这个函数就不再是inline,因为虚函数要放到虚表中去。
(2).静态成员不能被声明为虚函数。