dynamic_cast

dynamic_cast <new_type> (expression) 动态转换

 

动态转换确保类指针的转换是合适完整的,它有两个重要的约束条件,其一是要求new_type为指针或引用,其二是下行转换时要求基类是多态的(基类中包含至少一个虚函数)。

看一下下面的例子:

复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class CBase { };
 4 class CDerived: public CBase { };
 5 
 6 int main()
 7 {
 8 CBase b; CBase* pb;
 9 CDerived d; CDerived* pd;
10 
11 pb = dynamic_cast<CBase*>(&d);     // ok: derived-to-base
12 pd = dynamic_cast<CDerived*>(&b);  // wrong: base-to-derived 
13 }
复制代码

在最后一行代码有问题,编译器给的错误提示如下图所示:

把类的定义改成:

class CBase { virtual void dummy() {} };

class CDerived: public CBase {};

再编译,结果如下图所示:

编译都可以顺利通过了。这里我们在main函数的最后添加两句话:

cout << pb << endl;

cout << pd << endl;

输出pb和pd的指针值,结果如下:

我们看到一个奇怪的现象,将父类经过dynamic_cast转成子类的指针竟然是空指针!这正是dynamic_cast提升安全性的功能,dynamic_cast可以识别出不安全的下行转换,但并不抛出异常,而是将转换的结果设置成null(空指针)。

再举一个例子:

复制代码
 1 #include <iostream>
 2 #include <exception>
 3 using namespace std;
 4 
 5 class CBase { virtual void dummy() {} };
 6 class CDerived: public CBase { int a; };
 7 
 8 int main () {
 9   try {
10     CBase * pba = new CDerived;
11     CBase * pbb = new CBase;
12     CDerived * pd;
13 
14     pd = dynamic_cast<CDerived*>(pba);
15     if (pd==0) cout << "Null pointer on first type-cast" << endl;
16 
17     pd = dynamic_cast<CDerived*>(pbb);
18     if (pd==0) cout << "Null pointer on second type-cast" << endl;
19 
20   } catch (exception& e) {cout << "Exception: " << e.what();}
21   return 0;
22 }
复制代码

输出结果是:Null pointer on second type-cast

两个dynamic_cast都是下行转换,第一个转换是安全的,因为指向对象的本质是子类,转换的结果使子类指针指向子类,天经地义;第二个转换是不安全的,因为指向对象的本质是父类,“指鹿为马”或指向不存在的空间很可能发生!

最后补充一个特殊情况,当待转换指针是void*或者转换目标指针是void*时,dynamic_cast总是认为是安全的,举个例子:

复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class A {virtual void f(){}};
 4 class B {virtual void f(){}};
 5 
 6 int main() {
 7     A* pa = new A;
 8     B* pb = new B;
 9     void* pv = dynamic_cast<void*>(pa);
10     cout << pv << endl;
11     // pv now points to an object of type A
12 
13     pv = dynamic_cast<void*>(pb);
14     cout << pv << endl;
15     // pv now points to an object of type B
16 }
复制代码

运行结果如下:

可见dynamic_cast认为空指针的转换安全的,但这里类A和类B必须是多态的,包含虚函数,若不是,则会编译报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值