将指针或引用,沿着继承层次(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不是指向正在构造/析构的对象本身的类型或它的基类, 那么该行为是未定义的。 [未完待续…]
新闻热点
疑难解答