C++ Programmer's Cookbook

{C++ 基础} {C++ 高级} {C#界面,C++核心算法} {设计模式} {C#基础}

dynamic_cast使用的讨论


一 问题
1)什么时候应必须使用dynamic_cast
2)什么时候dynamic_cast可以使用static_cast代替

二 实例
// TestCast.cpp : Defines the entry point for the console application.
//

#include 
"stdafx.h"
#include 
<iostream>
using namespace std;

class Base
{
 
public:
    
virtual void f() { cout << "Base::f" << endl; }
    
void f1(){cout << "Base::f1" << endl;}
private:
    
double x;
    
double y;
}
;
class Derived : public Base
{
public:
    
virtual void f(){cout << "Derived::f" << endl; }
    
virtual void k(){cout << "Derived::k" << endl; }
private:
    
double z;
}
;

class Base1
{
public:
    
virtual void g(){ cout << "Base1::g" << endl;}
    
void g1(){cout << "Base1::g1" << endl;}
}
;
class Derived1 : public Base,public Base1
{
public:
    
virtual void f(){ cout << "Derived1::f" << endl;}
    
virtual void h(){ cout << "Derived1::h" << endl;}
}
;

void Test1()
{

    
// 对于单继承,
    
// 如果PD真的指向Derived,用dynamic_cast和static_cast效果相同
    Base *pD = new Derived;
    Derived 
*pD1 = dynamic_cast<Derived*>(pD);
    pD1
->f();
    pD1
->k();
    pD1
->f1();

    Derived 
*pD2 = static_cast<Derived*>(pD);
    pD2
->f();
    pD2
->k();
    pD2
->f1();


    
// 但是如果PB不是真的指向Derived,则用dynamic_cast则返回NULL,能够更早的禁止error的发生,
    
// 如果用static_cast虽然返回的不为NULL,但是运行时可能抛出exception。
    //// Error code 
    //Base *pB = new Base();
    
//Derived *pD3 = static_cast<Derived*>(pB);
    
//pD3->f();
    
//pD3->k();
    
//pD3->f1();

    
//Derived *pD4 = dynamic_cast<Derived*>(pB);
    
//pD4->f();
    
//pD4->k();
    
//pD4->f1();
}


void Test2()
{
    
// 对于多重继承,
    
// 如果PD真的指向的是Derived1,使用dynamic_cast和static_cast都可以转化为Derived1,
    
// 但是如果要转化为Base的兄弟类Base1,必须使用dynamic_cast,使用static_cast不能编译。
    Base *pD = new Derived1;
    Derived1 
*pD1 = dynamic_cast<Derived1*>(pD);
    pD1
->f();
    pD1
->h();
    pD1
->f1();

    Base1 
*pB1 = dynamic_cast<Base1*>(pD);
    pB1
->g();

    Derived1 
*pD2 = static_cast<Derived1*>(pD);
    pD2
->f();
    pD1
->h();
    pD2
->f1();

    
//// error can not compiler
    //Base1 *pB2 = static_cast<Base1*>(pD);
    
//pB2->g();

    
// 当然对于PB不是真的指向Derived1,想要转化为Derived1或Base的兄弟类Base1,情况与Test1中的error情况相同。


}


int _tmain(int argc, _TCHAR* argv[])
{
    Test1();

    Test2();

    
return 0;
}



三 结论

大家先总结下,哈哈!

posted on 2008-02-19 10:08 梦在天涯 阅读(12652) 评论(6)  编辑 收藏 引用 所属分类: CPlusPlus

评论

# re: dynamic_cast使用的讨论 2008-02-19 14:54 rednight

貌似不管啥时候用dynamic_cast都要安全一些啊  回复  更多评论   

# re: dynamic_cast使用的讨论 2008-02-19 16:08 逍遥剑客

效率上有差别啊  回复  更多评论   

# re: dynamic_cast使用的讨论 2008-02-19 19:20 键盘的咏叹调

dynamic_cast依赖虚函数并且会造成运行时的效率缺失

static_cast不依赖虚函数  回复  更多评论   

# re: dynamic_cast使用的讨论 2008-07-10 23:46 cexer

在实际的项目当中,可以自己实现dynamic_cast的运行时安全,并且更具有效率的转换方法。com也能一种。  回复  更多评论   

# re: dynamic_cast使用的讨论 2009-04-10 13:47 qq156875080

上面的我调试过,不能在VC6.0中调试通过的,要进行project设置的(具体设置可以加我QQ联系,注明dynamic)
而且这个程序是不安全的,new了一个pD,却没有释放它,要么采用“test(Base *pD)的书写形式,要么最后加上“delete pD"操作。
而且对于你”error code“里面的东西调试发现,是可以通过的,只是这时的PD3获得的是一个base类型的指针,或者说pd3初始化为一个point to(指向)base的指针,所以这时pd3对base的f 和 f1 的调用是成功的(返回当然是base::f 与 base::f1了)。只是在调用K时失败。
个人理解:动态转换其实是一个类家族的安全检查和公共界面问题,上面例子知道了一个类的父类的时候,看上去没有什么用,你把dynamic和base *都去掉,直接new derived ,结果还是一样的。有时在不知道父类时或者不确定你的类是否是父类的override时,你在想用这种公共界面,为了类型安全(也就是确定他们是一个家族中的类),就要用到这种强制转换
说的不好的,望大家指出,一起讨论  回复  更多评论   

# re: dynamic_cast使用的讨论 2011-11-08 11:33 leeco

没有必须使用dynamic_cast的时候,
Base1 *pB1 = static_cast<Base1*>(static_cast<Derived1*>(pD));   回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

EMail:itech001#126.com

导航

统计

  • 随笔 - 461
  • 文章 - 4
  • 评论 - 746
  • 引用 - 0

常用链接

随笔分类

随笔档案

收藏夹

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

积分与排名

  • 积分 - 1632804
  • 排名 - 5

最新评论

阅读排行榜