动态类型转换dynamic_cast

Posted 放不下的小女孩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态类型转换dynamic_cast相关的知识,希望对你有一定的参考价值。

  

  C++Primer第十九章的动态类型转换部分讲的不是很清楚,于是自己查cpp的官方手册总结一下。

dynamic_cast < new-type > ( expression )        

  动态类型转换是可以安全的在继承体系将指针和引用进行向上、向下和横向的转换。其表达式的类型为运行时的动态类型。具体功能如下:

 

  一、和隐式转换,静态转换static_cast一样的功能

 

  1、增加const属性:在expression和new-type类型相同或new-type为void*时,转换结果为expression的指针或引用。并且可以在dynamic_cast前加上const限定符实现增加const属性。

const dynamic_cast < new-type > ( expression ) 

  2、向上转换upcast:和static_cast和隐式转换一样,dynamic_cast可以将派生类转换为基类。

 

  二、dynamic_cast独有的功能

  如果expression是一个指向具有多态特性的基类Base的指针或引用(静态类型),new-type是一个指向派生类Derived对象的指针或引用,具体进行那种转换根据expression的动态类型判断

 

  1、向下转换downcast:expression的动态类型为指向派生类Derived的指针或引用,并且Derived仅包含一份继承自Base的对象,则转换结果为指向Derived对象的指针或引用。(相当于从expressionh的父类转换为子类

  2、横向转换sidecast:expression的动态类型为指向一个类的对象的指针或引用,该类公有继承自Base和Derivied(Derived不一定继承自Base)并且继承自Derived的子成员是明确的(必须是虚继承,不能有二义性)。则转换结果为指向Derived的指针或引用。(相当于expression动态类型对象的一个父类转换为另一个父类)

 

  三、转换失败时如果转换目标是指针类型则返回空指针,引用类型抛出一个bad_cast异常。

 

  这里直接使用官方例子

 1 #include <iostream>
 2  
 3 struct V {
 4     virtual void f() {}  // must be polymorphic to use runtime-checked dynamic_cast
 5 };
 6 struct A : virtual V {};
 7 struct B : virtual V {
 8   B(V* v, A* a) {
 9     // casts during construction (see the call in the constructor of D below)
10     dynamic_cast<B*>(v); // well-defined: v of type V*, V base of B, results in B*
11     dynamic_cast<B*>(a); // undefined behavior: a has type A*, A not a base of B
12   }
13 };
14 struct D : A, B {
15     D() : B(static_cast<A*>(this), this) { }
16 };
17  
18 struct Base {
19     virtual ~Base() {}
20 };
21  
22 struct Derived: Base {
23     virtual void name() {}
24 };
25  
26 int main()
27 {
28     D d; // the most derived object
29     A& a = d; // upcast, dynamic_cast may be used, but unnecessary
30     [[maybe_unused]]
31     D& new_d = dynamic_cast<D&>(a); // downcast
32     [[maybe_unused]]
33     B& new_b = dynamic_cast<B&>(a); // sidecast
34  
35  
36     Base* b1 = new Base;
37     if(Derived* d = dynamic_cast<Derived*>(b1))
38     {
39         std::cout << "downcast from b1 to d successful\\n";
40         d->name(); // safe to call
41     }
42  
43     Base* b2 = new Derived;
44     if(Derived* d = dynamic_cast<Derived*>(b2))
45     {
46         std::cout << "downcast from b2 to d successful\\n";
47         d->name(); // safe to call
48     }
49  
50     delete b1;
51     delete b2;
52 }

  输出结果

downcast from b2 to d successful

 

参考文献:dynamic_cast conversion - cppreference.com

以上是关于动态类型转换dynamic_cast的主要内容,如果未能解决你的问题,请参考以下文章

dynamic_cast 与 typeid

运行时类型信息RTTI

dynamic_cast, RTTI, 整理

static_cast, dynamic_cast, const_cast讨论

C/C++杂记:运行时类型识别(RTTI)与动态类型转换原理

为什么要使用dynamic_cast