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