c++之 虚函数 虚函数指针 虚函数表指针 虚函数表
最近碰到虚函数,看了一遍后,以为自己明白了,后来发现并没有,网上的帖子给了一些帮助,但大部分说的不太清楚,来来回回理了好几遍,谨以此记录。
1、函数一旦声明成了虚函数,在所有子类中都是虚函数,如果子类要覆盖,那行参和返回类型必须和父类一致,virtual关键字可写可不写。
2、每个类的对象,都有一个虚函数表指针,一般存在于对象实例中最前面的位置(不同编译器不同),指向该类的虚函数表,虚函数表属于类,存储所有虚函数地址(即虚函数指针,怎么存的见4),虚函数指针占用类的内存空间,虚函数表不占用。
3、如果一个父类指针指向了子类对象:
3.1 此子类对象会做裁剪,会没有子类中独有的成员函数(A中有f()、g(),B继承A,B中有f()、g()、h(),A指针指向B对象,即 B b; A *a = &b,此时a是调用不到h的,无论h是否为虚函数)
3.2 对于从父类继承过来的非虚函数(如果不是从父类继承过来的,参数3.1),此子类对象会调用父类的
3.3 对于从父类继承过来的虚函数(如果不是从父类继承过来的,参照3.1),如果有重写,那会调用重写的,如果没重写,那就会调用基类的
3.4 父类的析构函数必须为虚函数,不然就会出现3.2的情况,可能导致子类没有被析构
4、每个类的虚函数表中如何存放虚函数指针的
4.1 按虚函数声明顺序依次存放,父类在前,子类在后,以”.”作为虚函数表结尾标识符,不同编译器下使用不同标识符
A::f() |
A::g() |
B::f1() |
B:g1() |
4.2 若子类中有覆盖父类的虚函数,那在子类的函数表中,子类中覆盖的虚函数会放到原父类虚函数的位置,没有被覆盖的函数没有变化
B::f() |
A::g() |
B::f1() |
B::g1() |
4.3 若多重继承 且 没有覆盖,每个父类都有自己的虚函数表;子类的虚函数表被放到第一个父类的虚函数表中
-->
(此图片来源网络)
4.4 若多重继承 且 有覆盖,会结合4.3 和4.2(与4.2不同的是,所有父类虚函数表中被覆盖的虚函数都会替换成子类的虚函数)
-->
(此图片来源网络)
附大牛地址:
https://www.cnblogs.com/yinbiao/p/10987640.html
https://blog.****.net/JackZhang_123/article/details/80692420
后续还有新的收获再更新。。。。