作用:
什么是多态:调用同一个函数(接口)表现出不同的结果
多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。
C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
函数重写(函数覆盖):
1. 函数名相同
2. 入参一样,返回值相同
3. 作用域不一样,一个位于基类,一个位于派生类。
4. 基类的函数必须加virutal,派生类的同名函数可以加可不加。
5. 访问限定符可以不一样
虚函数:
虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。
纯虚函数:
您可能想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。
怎么样实现多态?
1. 派生类重写基类的虚函数
2. 通过基类的指针指向派生类对象,通过基类指针调用虚函数,可以保证接口高度统一
赋值兼容规则
基类的指针可以指向派生类对象,而派生类指针不能指向基类的对
象
纯虚函数:虚函数 =0;
包含纯虚函数的类叫抽象类,抽象类无法创建对象。函数重载、函数重写(覆盖)、函数隐藏的区别?
1、成员函数覆盖(override,也称重写)
是指派生类重新定义基类的虚函数,特征如下:
A、不同的作用域(分别位于派生类与基类)
B、函数名字相同
C、参数相同
D、基类函数必须有virtual关键字,不能有static
E、返回值相同
F、重写函数的权限访问限定符可以不同
2、函数重载(overload)
是指函数名相同,参数不同(数量、类型、次序),特征如下:
A、相同的范围(在同一个作用域中)
B、函数名字相同
C、参数不同
D、virtual 关键字可有可无
E、返回值可以不同静态联编(静态链接)
是指在编译阶段就将函数实现和函数调用关联起来,因此静态联编也叫早绑定,函数重载是早绑定
动态联编(动态链接)
是指在程序执行的时候才将函数实现和函数调用关联,因此也叫运行时绑定或者晚绑定。
C++中一般情况下联编也是静态联编,但是一旦涉及到多态和虚拟函数就必须要使用动态联编了
3、成员函数隐藏(也称重定义,尽量不去写)
A、不在同一个作用域(分别位于派生类与基类)
B、函数名字相同
C、返回值可以不同
D、参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意与重载的区别)
E、参数相同,但是基类函数没有 virtual关键字。此时,基类的函数被隐藏(注意与覆盖的区别)
多态的原理:虚函数表
通过基类的指针或引用调用虚函数,到底调用是基类的虚函数还是派生类重写后的虚函数,
看的是对象,而不是指针的数据类型。
原因:虚函数的调用会查虚函数表,每个对象的虚函数表不一样,调用的虚函数就不一样。
虚析构
析构函数前为什么加virtual关键字?
只有虚函数的调用,是看对象不同查对象的虚函数表,其他看指针或引用的数据类型。
如果不在析构函数前加virtual ,在某些情况下会产生内存泄漏。推荐在析构函数前加virtual
构造函数前为什么加explicit关键字?
给单参数的构造函数前使用explicit关键字,阻止可能产生的隐式转换:由成员变量类型转换为类类型。