2. 转型 + 继承链

有如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class A
{
protected:
virtual show(){}
};
class B : public A
{
protected:
virtual show(){}
};
class C : public B
{
protected:
virtual show(){}
}
int main()
{
A* p1 = new C;
B* p2 = dynamic_cast<B*>(p1); //L1
A* p3 = new A;
B* p2 = dynamic_cast<B*>(p3); //L2
return 0;
}

A. L 1语句编译失败,L 2语句编译通过 B. L1语句编译通过,L2语句编译失败 C. L 1,L 2都编译失败 D. L 1,L 2都编译通过

四种类型转换符:

  1. static_cast:用于良性转换,一般不会导致意外发生,风险很低。
  2. const_cast:用于 const 与非 const、volatile 与非 volatile 之间的转换。
  3. reinterpret_cast:高度危险的转换,仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,但可实现最灵活的 C++ 类型转换。
  4. dynamic_cast借助 RTTI,用于类型安全的向下转型(Downcasting)。

向下转型

当使用 dynamic_cast 对指针进行类型转换时,程序会先找到该指针指向的对象,再根据对象找到当前类(指针指向的对象所属的类)的类型信息(type_info),并从此节点开始沿着继承链向上遍历,如果找到了要转化的目标类型,那么说明这种转换是安全的,就能够转换成功,如果没有找到要转换的目标类型,那么说明这种转换存在较大的风险,就不能转换。

image-20220619132309381

故而L1编译能够通过,而L2无法通过编译。