二、dynamic_cast 

dynamic_cast 仅允许把 指针类型或引用类型 转换成 对象,从而获得一个完整的对象。通常的应用场景是,把派生类的指针转换成基类的指针。

看以下程序dynamic_cast.cpp:

 1 int main(){ 
 2         CBase b; CBase* pb;
 3         CDerived d; CDerived* pd;
 4         pb = dynamic_cast<CBase*>(&d);     // ok: derived-to-base
 5         pd = dynamic_cast<CDerived*>(&b);  // wrong: base-to-derived
 6 
 7         int dwA=10, *pB = NULL; 
 8         short int *pA=NULL, wB =20; 
 9         pA = dynamic_cast<short int *> (&dwA); // wrong:
10         pB = dynamic_cast<int *> (&wB); // wrong:
11 }

 

第5行编译错误的原因是:cannot dynamic_cast '& b' (of type 'class CBase*') to type 'class CDerived*' (source type is not polymorphic).  基类指针不能通过dynamic_cast 转换成派生类指针

第9行编译错误的原因是:cannot dynamic_cast '& dwA' (of type 'int*') to type 'short int*' (target is not pointer or reference to class)    dynamic_cast操作符的target和source都必须是指向某对象的指针或引用,而不能是指向基本数据结构的指针。

第10行和第9行的原因一样。

 

在使用多态特性时,dynamic_cast操作符因为在编译器无法判断类型转换是否“合理”,不会在编译期提示错误。 但是当遇到基类指针通过dynamic_cast转化成派生类指针时(如dynamic_cast_polymorphic.cpp的第15行),会返回空指针。

 1 // dynamic_cast_polymorphic.cpp
 2 #include <iostream>
 3 #include <exception>
 4 using namespace std;
 5 
 6 class CBase { virtual void dummy() {} };
 7 class CDerived: public CBase { int a; };
 8 
 9 int main () {
10   try {
11     CBase * pb1 = new CDerived;
12     CBase * pb2 = new CBase;
13     CDerived * pd1, *pd2;
14     pd1 = dynamic_cast<CDerived*>(pb1);// derived -> derived
15     pd2 = dynamic_cast<CDerived*>(pb2);// base -> derived, pd2 is null pointer.
16     cout<<endl;
17   }
18   catch (exception& e) {cout << "Exception: " << e.what();}
19   return 0;
20 }
通过gdb可以看到各指针所指向的实际地址。
(gdb) print pb1
$1 = (CBase *) 0x502010
(gdb) print pb2
$2 = (CBase *) 0x502030
(gdb) print pd1
$3 = (CDerived *) 0x502010
(gdb) print pd2
$4 = (CDerived *) 0x0    // 空指针

 

参考:

http://www.cplusplus.com/doc/tutorial/typecasting/

 

 

posted on 2012-09-17 17:34  yaozhaoyz  阅读(367)  评论(0编辑  收藏  举报