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