虚基类,虚函数,虚析构函数,纯虚函数,虚函数表(待补充)
一.虚基类——在继承方式(public / private)之前加 virtual
class B1: virtual public B0{};
作用:防止多重继承中二义性,保证成员唯一标识是核心。
【比较】 作用域分辨符:: vs 虚基类
相同:都是为了保证 唯一标识成员
不同:①“::” 在派生类中,同名成员有多个拷贝,通过积累名来唯一标识。可以容纳更多数据 D1 d1; d1.B1 :: nV = 2;
②虚基类,只维护一份成员拷贝。更节省内存
二.虚函数——函数声明前加 virtual
virtual void Display( ){}
虚函数是动态绑定的基础。 一般将基类中的同名函数声明为 virtual。
用基类类型指针指向派生类对象,则通过基类指针可以使属于不同派生类的不同对象产生不同的行为,从而实现动态绑定。
动态绑定三个条件(官方版):①类之间满足类型兼容规则
②(一般基类中)声明虚函数
③由成员函数来调用 或者通过指针、引用来访问虚函数
【注意】构造函数不能为虚
“虚函数的意思就是开启动态绑定,程序会根据对象的动态类型来选择要调用的方法。然而在构造函数运行的时候,这个对象的动态类型还不完整,没有办法确定它到底是什么类型,故构造函数不能动态绑定。(动态绑定是根据对象的动态类型而不是函数名,在调用构造函数之前,这个对象根本就不存在,它怎么动态绑定?)”
“虚函数采用一种须调用的方法。虚调用是一种可以在只有部分信息情况下工作的机制,特别是允许调用一个只知道接口而不知道其准确对象类型的函数。
但是要创造一个对象(构造函数),必须要知道对象的准确类型。”(程序员面试宝典4版P118)
三.虚析构函数
virtual ~类名();
其他同 一般的虚函数,示例代码传送门:
四.纯虚函数—— 普通虚函数后加“ =0 ”
virtual 函数类型 函数名(参数表)=0;
用处:对基类中不实现的函数,则在基类中只声明原型来规定整个类族的同一接口,而在派生类中给出具体的实现,避免代码冗余(别的作用??)
【注意】①在基类同时也是抽象类中声明(因为带有纯虚函数的类就是抽象类); ②只有声明没有实现部分,即没有函数体
【函数体为空的虚函数 vs 纯虚函数】相同:都能派生新的类,实现动态绑定
不同:
函数体为空的虚函数 | 纯虚函数 | |
函数体 | 有,只是为空 | 根本没有函数体 |
所在类 | 普通基类 | 抽象类 |
实例化 | 可以 | 不能直接实例化 |
*********笔面试题目**********************************************
参考: