面试题答案
一键面试1. 引用和指针的向上转换
- 过程:
- 指针:派生类指针可以直接赋值给基类指针,例如
Derived d; Base* b = &d;
,这是因为派生类对象包含基类对象的所有成员,这种转换是隐式的,不需要额外的操作符。 - 引用:派生类引用也可以隐式转换为基类引用,如
Derived d; Base& b = d;
,同样因为派生类对象中包含基类子对象。
- 指针:派生类指针可以直接赋值给基类指针,例如
- 可能遇到的问题:这种转换基本没有运行时错误风险,但通过基类指针或引用只能访问基类中定义的成员,可能丢失派生类特有的成员访问权限。
2. 引用和指针的向下转换
- 过程:
- 指针:使用
dynamic_cast
进行向下转换,例如Base* b = new Derived(); Derived* d = dynamic_cast<Derived*>(b);
。dynamic_cast
在运行时检查指针所指向的对象实际类型是否与目标类型(这里是Derived
)一致,如果一致则返回有效的派生类指针,否则返回nullptr
。 - 引用:由于引用不能为空,所以
dynamic_cast
用于引用时,如果转换失败会抛出std::bad_cast
异常。例如Base& b = *new Derived(); try { Derived& d = dynamic_cast<Derived&>(b); } catch (std::bad_cast& e) { // 处理异常 }
。
- 指针:使用
- 可能遇到的问题:
- 使用
dynamic_cast
的前提:要进行dynamic_cast
的类必须包含虚函数,否则编译会报错。因为dynamic_cast
依赖于运行时类型信息(RTTI),而RTTI是基于虚函数机制实现的。 - 性能开销:
dynamic_cast
是运行时操作,相比编译时的静态转换(如static_cast
)有一定的性能开销,因为它需要在运行时检查对象的实际类型。 - 多重继承场景:在多重继承情况下,
dynamic_cast
的行为会更复杂。如果派生类从多个基类继承,dynamic_cast
不仅要检查类型,还需要处理对象内存布局的调整,可能导致转换后的指针值发生变化。
- 使用