MST

星途 面试题库

面试题:C++不同继承方式下虚基类访问在多继承场景的复杂情况

假设有类A为虚基类,类B和类C以不同继承方式(public、private、protected中选两种)继承自A,然后类D多继承自B和C。请详细说明在类D的成员函数中访问虚基类A成员的具体规则,包括访问权限及可能涉及的隐藏、重写等问题。
11.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 继承方式分析

    • 假设Bpublic方式继承ACprivate方式继承A
      • B类以public继承A,意味着A中的public成员在B中仍为publicprotected成员在B中仍为protected
      • C类以private继承A,则A中的publicprotected成员在C中都变为private
  2. 类D的访问权限

    • 对于public继承的B部分
      • 在类D的成员函数中,可以直接访问从B继承过来的Apublicprotected成员。例如,如果A有一个public函数void funcA(),在D的成员函数中可以像这样调用:this->funcA();(假设funcA没有被B隐藏或重写)。
    • 对于private继承的C部分
      • 由于Cprivate方式继承AA的成员在C中变为private,所以在类D的成员函数中无法直接访问从C继承过来的A的成员(即使是Apublic成员)。
  3. 隐藏和重写问题

    • 隐藏
      • 如果BC定义了与A中同名的成员(函数或变量),则会隐藏A中的该成员。例如,A有一个函数void funcA()B中也定义了void funcA(),那么在D中通过B访问AfuncA时,实际访问到的是BfuncA,而不是AfuncA。如果要访问AfuncA,需要使用作用域解析符A::funcA();(前提是访问权限允许)。
    • 重写
      • 如果A中的函数是虚函数(例如virtual void funcA()),BC重写了该虚函数(void funcA() override;),在D的成员函数中调用该函数时,会根据对象的实际类型进行动态绑定。如果D对象的实际类型决定调用B重写的版本,则会调用BfuncA,如果决定调用C重写的版本,则会调用CfuncA。例如,如果通过D对象指针D* dPtr = new D(); dPtr->funcA();,根据funcA的动态绑定规则,会调用实际重写版本的函数。
  4. 总结

    • 在类D的成员函数中,对于以public继承方式从虚基类A继承来的成员,可根据其在虚基类中的访问权限(publicprotected)直接访问;对于以private继承方式从虚基类A继承来的成员,在类D成员函数中无法直接访问。同时要注意隐藏和重写带来的访问变化,隐藏时可通过作用域解析符访问被隐藏的虚基类成员,重写时遵循虚函数的动态绑定规则。