将指针或引用,沿着继承层次(inheritance hierarchy) 向上、向下安全转型。当 new_type
是指针类型时, 如果转换失败, 则返回 nullptr
, 当 new_type
是引用类型时, 如果转换失败, 则抛出异常。使用方式如下:
只有当下列转换不移除变量的 const
和 volatile
性质时, 才使用 dynamic_cats
:
expression
正好是 new_type
类型的变量, 或者 new_type
是 expression
的类型加上了 cv限定符(cv-qualifier) 。(也就是说, dynamic_cast
可以用来加 cv限定符。隐式转换(implicit cast) 和 static_cast
也可以用来实现该功能) 其返回值是 new_type
类型, 值是 expression
的值。experssion
是空指针。 其返回值是 new_type
类型的空指针。new_type
是指向 Base
的指针或者引用, expression
的类型是指向 Derived
的指针或引用(其中 Base
是 Derived
唯一的、accessible 基类。【译者注: accessible 在这里实在不好翻译和解释。 这么说吧, 当子类 private
继承基类时, 这个基类就是该子类的 inaccessible base
, 这个基类就不能向上转型为该基类】)。(隐式转换(implicit cast) 和 static_cast
也可以用来实现该功能) 其返回值是基类指针或引用类型。expression
是指向多态类型的指针或引用, new_type
是 void*
类型。 返回值是 void*
类型, 值是最底层的子类对象(the most derived object)的地址。 如:
#include <iostream>using namespace std;class Base {public: virtual void func() { }};class Base1 {public: virtual void func1() { }};class Derived : public virtual Base, public virtual Base1{public:};int main() { Derived* p = new Derived; cout << "Derived: " << hex << p << endl; cout << "--------------------------------" << endl; Base* pb = dynamic_cast<Base*>(p); cout << "Derived->Base: " << hex << pb << endl; Base1* pb1 = dynamic_cast<Base1*>(p); cout << "Derived->Base1: " << hex << pb1 << endl; cout << "--------------------------------" << endl; void* vpb = dynamic_cast<void*>(pb); cout << "Derived->Base->void: " << hex << vpb << endl; void* vpb1 = dynamic_cast<void*>(pb1); cout << "Derived->Base1->void: " << hex << vpb1 << endl; return 0;}输出结果:
Derived: 0x1b14f0--------------------------------Derived->Base: 0x1b14f0Derived->Base1: 0x1b14f8--------------------------------Derived->Base->void: 0x1b14f0Derived->Base1->void: 0x1b14f0如果expression
的类型是指向多态类型 Base
的指针或引用, new_type
是指向 Derived
类型的指针或引用, 将会进行运行时检查(run-time check): a) expression
指向的类型(Base)是 Derived
的 public
继承的基类。返回结果是 Derived
类型指针/引用。(downcast) b) expression
指向的类型(Base)是某个类 MostDerived
的一个 public
基类, 同时, new_type
指向的类型(Derived)是 MostDerived
的一个 public
基类(译者注: 并且要求, Derived
既不是 Base
的子类, 也不是它的基类)。 返回结果是 Derived
类型指针/引用。(sidecast) c) 否则, 运行时检查(run-time check) 失败。 如果 dynamic_cast
使用在指针上, 则 new_type
类型的空指针, 否则抛出异常。dynamic_cast
被直接或间接用在构造或析构函数, 并且 expression
指向的正是当前正在构造/析构的对象。 但是, 如果 new_type
不是指向正在构造/析构的对象本身的类型或它的基类, 那么该行为是未定义的。 [未完待续…]
新闻热点
疑难解答