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 若多重继承 且 没有覆盖,每个父类都有自己的虚函数表;子类的虚函数表被放到第一个父类的虚函数表中

 

c++之 虚函数 虚函数指针 虚函数表指针 虚函数表  --> c++之 虚函数 虚函数指针 虚函数表指针 虚函数表  

(此图片来源网络)

      4.4 若多重继承 且 有覆盖,会结合4.3 和4.2(与4.2不同的是,所有父类虚函数表中被覆盖的虚函数都会替换成子类的虚函数)

c++之 虚函数 虚函数指针 虚函数表指针 虚函数表 -->   c++之 虚函数 虚函数指针 虚函数表指针 虚函数表

(此图片来源网络)

附大牛地址:

https://www.cnblogs.com/yinbiao/p/10987640.html

https://blog.****.net/JackZhang_123/article/details/80692420

后续还有新的收获再更新。。。。