C++虚函数易错点整理
目录
一、this指针
二、virtual关键字的使用
三、虚函数的定义
四、虚函数的使用情景
五、重载、重写以及重定义
六、赋值兼容
七、抽象类
八、虚表
一、this指针
静态成员函数没有this指针,也不支持重写,static和virtual是不能同时用的;静态成员函数属于整个类,可以用类域::成员函数名的方式访问,因为没有隐藏的this指针,因此也就无法拿到虚表,也就无法实现多态
二、virtual关键字的使用
·virtual用于声明虚函数,只在声明时加上,在类外定义时不能加
·想要实现多态的话,virtual就一定要加在父类的相应函数前,但是可以在子类的相应函数前不加,反过来加是不可以的
三、虚函数的定义
·虚函数只能是成员函数,友元函数不能作为虚函数
四、虚函数的使用情景
·使用虚函数是为了实现多态,因此如果不需要实现多态的话就不需要写虚函数,因为多态也会有额外的消耗,比如虚函数表这个函数指针数组
·子类的虚函数放在private里面,并不影响多态的实现,因为多态仅仅是用子类函数的地址覆盖虚表,并不该表调用的位置
五、重载、重写以及重定义
·重载是在相同作用域中的同名函数,拥有不同的参数(类型或者是数量不同),返回类型可以不同,来进行行为的函数
·重写就是覆盖,针对多态,重定义就是隐藏,两者都是要在同一个继承体系当中,但是父类和子类都有自己独立的作用域,因此重写和重定义不是重载;而重写要求三相同(函数名、返回类型、参数),但是协变除外(可以返回基类或子类的指针或者引用),在以上体系中只要不构成覆盖,就构成隐藏
六、赋值兼容
·即使已经将子类赋值给父类,但只要使用父类对象调用的方法就都是父类的方法
七、抽象类
·抽象类不能实例化出对象,因此将其作为实参、函数参数列表成员、返回值等都是不可以的;但是抽象类可以作为指针,并应用与将父类指针指向子类以实现多态
八、虚表
·一个类的不同成员共享该类的虚表,一个类可以有多个虚表(在多继承的情况下)
·父类函数和子类函数的前四个字节都用于存储一个数组指针,这个指针指向了各自的虚表,两个虚表中的内容不同(如果子类重写了虚函数的话)
·在多继承的情况下,对于子类而言,有几个父类就有几个虚表,但是他所新写的虚函数只会放在第一个虚表后面,其他的虚表也不会存储,因为存储了也不能调用