21:C++虚函数相关问题
虚函数表指针:
占四个内存单元, 指向一个虚函数表的起始位置,这个虚函数表存放着该类的所有虚函数指针,通过该表的偏移即可找到函数的入口地址,即要使用的虚函数。
虚函数实现原理
当实例化一个对象时,如果该类没有虚函数,却从其父类哪里继承了虚函数,该类也会有一个虚函数表和一个自己的虚函数表指针,但是表中所存放的虚函数指针却与自己的父类是一样的。
如果该类定义了从父类继承来的虚函数,同样该类有一个自己的虚函数表和一个自己的虚函数表指针,但是表中这个重写的函数所对应的指针会覆盖掉原来指向父类函数的指针的值,即指向了自己定义的相应函数,表中其它未定义的函数不变
当使用父类的指针指向子类的对象时,尽管指针的类型是父类的,但它的指向的地址与子类对象地址是同一个,所以它可以从虚函数表指针找到子类对象的虚函数表,进而找到相应的函数;但是如果希望用该指针调用子类自己的函数(非重写的父类虚函数),则编译不过,因为指针的类型是父类,该指针不知道子类空间中自己的变量或函数(非继承自父类)。
为什么父类的指针能找到子类的虚函数表
虚函数表指针一般放与首地址,如果父类有虚函数表,子类必定有;因为构造子类时先构造父类,所以使用父类的指针,编译器根据指针类型就能知道偏移多少就能找到父类的成员(包括虚函数指针),但是对于子类独有的成员,父类的指针无法提供偏移量,因此找不到。
多重继承时的虚函数
多重继承下,派生类有多个虚函数表,也有多个虚函数表指针,数目与所继承的父类的数目相同;这些表的顺序依照声明的顺序来排列,构造的顺序为:父类1的虚函数表,父类1的成员,父类2的虚函数表、父类2的成员…….。子类自己的虚函数(不是继承自任何一个父类的)被放到第一个父类的表中,如果发生虚函数覆盖,则不同表中所有相应的虚函数都被覆盖。当用某一个父类的指针指向派生类时,他们所指向的地址不是子类对象的地址,而是子类中自己的部分,即与自己对应的那个虚函数表。

最低0.47元/天 解锁文章
1929





