面试题答案
一键面试-
继承方式分析
- 假设
B
以public
方式继承A
,C
以private
方式继承A
。B
类以public
继承A
,意味着A
中的public
成员在B
中仍为public
,protected
成员在B
中仍为protected
。C
类以private
继承A
,则A
中的public
和protected
成员在C
中都变为private
。
- 假设
-
类D的访问权限
- 对于
public
继承的B
部分:- 在类
D
的成员函数中,可以直接访问从B
继承过来的A
的public
和protected
成员。例如,如果A
有一个public
函数void funcA()
,在D
的成员函数中可以像这样调用:this->funcA();
(假设funcA
没有被B
隐藏或重写)。
- 在类
- 对于
private
继承的C
部分:- 由于
C
以private
方式继承A
,A
的成员在C
中变为private
,所以在类D
的成员函数中无法直接访问从C
继承过来的A
的成员(即使是A
的public
成员)。
- 由于
- 对于
-
隐藏和重写问题
- 隐藏:
- 如果
B
或C
定义了与A
中同名的成员(函数或变量),则会隐藏A
中的该成员。例如,A
有一个函数void funcA()
,B
中也定义了void funcA()
,那么在D
中通过B
访问A
的funcA
时,实际访问到的是B
的funcA
,而不是A
的funcA
。如果要访问A
的funcA
,需要使用作用域解析符A::funcA();
(前提是访问权限允许)。
- 如果
- 重写:
- 如果
A
中的函数是虚函数(例如virtual void funcA()
),B
或C
重写了该虚函数(void funcA() override;
),在D
的成员函数中调用该函数时,会根据对象的实际类型进行动态绑定。如果D
对象的实际类型决定调用B
重写的版本,则会调用B
的funcA
,如果决定调用C
重写的版本,则会调用C
的funcA
。例如,如果通过D
对象指针D* dPtr = new D(); dPtr->funcA();
,根据funcA
的动态绑定规则,会调用实际重写版本的函数。
- 如果
- 隐藏:
-
总结
- 在类
D
的成员函数中,对于以public
继承方式从虚基类A
继承来的成员,可根据其在虚基类中的访问权限(public
、protected
)直接访问;对于以private
继承方式从虚基类A
继承来的成员,在类D
成员函数中无法直接访问。同时要注意隐藏和重写带来的访问变化,隐藏时可通过作用域解析符访问被隐藏的虚基类成员,重写时遵循虚函数的动态绑定规则。
- 在类