深入解析C++中的动态类型转换与静态类型转换运算符

2020-01-06 14:20:39刘景俊
易采站长站为您分析C++中的动态类型转换与静态类型转换运算符,即dynamic_cast与static_cast的用法,需要的朋友可以参考下  

dynamic_cast 运算符
将操作数 expression 转换成类型为type-id 的对象。
语法


dynamic_cast < type-id > ( expression )

备注
type-id 必须是一个指针或引用到以前已定义的类类型的引用或“指向 void 的指针”。如果 type-id 是指针,则expression 的类型必须是指针,如果 type-id 是引用,则为左值。
有关静态和动态强制转换之间区别的描述,以及各在什么情况下适合使用,请参见 static_cast。
在托管代码中的 dynamic_cast的行为中有两个重大更改。
为指针的dynamic_cast 对指向装箱的枚举的基础类型的指针将在运行时失败,则返回 0 而不是已转换的指针。
dynamic_cast 将不再引发一个异常,当 type-id 是指向值类型的内部指针,则转换在运行时失败。该转换将返回 0 指示运行值而不是引发。
如果 type-id 是指向 expression的明确的可访问的直接或间接基类的指针,则结果是指向 type-id 类型的唯一子对象的指针。例如:


// dynamic_cast_1.cpp
// compile with: /c
class B { };
class C : public B { };
class D : public C { };

void f(D* pd) {
  C* pc = dynamic_cast<C*>(pd);  // ok: C is a direct base class
                  // pc points to C subobject of pd 
  B* pb = dynamic_cast<B*>(pd);  // ok: B is an indirect base class
                  // pb points to B subobject of pd
}

此转换类型称为“向上转换”,因为它将在类层次结构上的指针,从派生的类移到该类派生的类。向上转换是一种隐式转换。
如果 type-id 为 void*,则做运行时进行检查确定 expression的实际类型。结果是指向 by expression 的完整的对象的指针。例如:


// dynamic_cast_2.cpp
// compile with: /c /GR
class A {virtual void f();};
class B {virtual void f();};

void f() {
  A* pa = new A;
  B* pb = new B;
  void* pv = dynamic_cast<void*>(pa);
  // pv now points to an object of type A

  pv = dynamic_cast<void*>(pb);
  // pv now points to an object of type B
}

如果 type-id 不是 void*,则做运行时进行检查以确定是否由 expression 指向的对象可以转换为由 type-id指向的类型。
如果 expression 类型是 type-id类型的基类,则做运行时检查来看是否 expression 确实指向 type-id类型的完整对象。如果为 true,则结果是指向 type-id类型的完整对象的指针。例如:


// dynamic_cast_3.cpp
// compile with: /c /GR
class B {virtual void f();};
class D : public B {virtual void f();};

void f() {
  B* pb = new D;  // unclear but ok
  B* pb2 = new B;

  D* pd = dynamic_cast<D*>(pb);  // ok: pb actually points to a D
  D* pd2 = dynamic_cast<D*>(pb2);  // pb2 points to a B not a D
}