MST

星途 面试题库

面试题:多重继承下C++虚函数内存布局的复杂性

考虑一个C++类继承体系,A为基类且含有虚函数,B和C继承自A,D多重继承自B和C。请详细描述D类对象的内存布局中虚函数表的情况,包括虚函数表的数量、每个虚函数表的内容以及它们与基类虚函数表的关系,同时说明在这种复杂继承关系下,运行时如何准确调用正确的虚函数。
30.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 虚函数表的数量
    • 由于D多重继承自BC,而BC又继承自含有虚函数的A类,D类对象会有两个虚函数表。这是因为在多重继承中,为了支持从不同基类的角度正确调用虚函数,每个直接基类(这里是BC)都需要有自己独立的虚函数表指针,指向对应的虚函数表。
  2. 每个虚函数表的内容
    • 第一个虚函数表(与B相关)
      • 该虚函数表中首先会包含A类的虚函数(如果B没有重写,就使用A类虚函数的地址;如果B重写了,就使用B类重写后的虚函数地址)。
      • 然后会包含B类自己新增的虚函数(如果有)。
    • 第二个虚函数表(与C相关)
      • 同样,该虚函数表会先包含A类的虚函数(处理方式同B类虚函数表中对A类虚函数的处理)。
      • 接着包含C类自己新增的虚函数(如果有)。
  3. 与基类虚函数表的关系
    • D类对象中的两个虚函数表与A类虚函数表密切相关。它们都从A类虚函数表继承内容。对于A类的虚函数,在BC继承时可能会有重写操作,所以D类的两个虚函数表中A类虚函数部分可能与A类虚函数表有所不同(取决于BC是否重写)。而BC各自新增的虚函数则是对虚函数表的扩展,是A类虚函数表所没有的。
  4. 运行时虚函数调用
    • 在运行时,当通过D类对象或指向D类对象的指针、引用调用虚函数时,编译器会根据对象的类型信息(通常通过RTTI,运行时类型识别)和调用虚函数的上下文(即从哪个基类的角度调用)来确定使用哪个虚函数表。
    • 例如,如果通过D类对象以B类的视角调用虚函数,就会使用与B相关的虚函数表。编译器会根据虚函数表指针找到对应的虚函数表,然后在虚函数表中根据虚函数的索引找到正确的虚函数地址并调用。同样,如果以C类的视角调用虚函数,就会使用与C相关的虚函数表进行查找和调用。这样就能在复杂的多重继承关系下准确调用正确的虚函数。