woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

dynamic_cast使用的讨论

 

http://www.cppblog.com/mzty/archive/2008/02/19/42929.html

 

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

二 实例

clip_image001// TestCast.cpp : Defines the entry point for the console application.
clip_image001//
clip_image001

clip_image001#include "stdafx.h"
clip_image001#include <iostream>
clip_image001
using namespace std;
clip_image001
clip_image001
class Base
clip_image002clip_image003
clip_image004{
clip_image005 
public:
clip_image006clip_image007   
virtual void f() clip_image004{ cout << "Base::f" << endl; }
clip_image006clip_image007   
void f1()clip_image004{cout << "Base::f1" << endl;}
clip_image005
private:
clip_image005   
double x;
clip_image005   
double y;
clip_image008}
;
clip_image001
class Derived : public Base
clip_image002clip_image003
clip_image004{
clip_image005
public:
clip_image006clip_image007   
virtual void f()clip_image004{cout << "Derived::f" << endl; }
clip_image006clip_image007   
virtual void k()clip_image004{cout << "Derived::k" << endl; }
clip_image005
private:
clip_image005   
double z;
clip_image008}
;
clip_image001
clip_image001
class Base1
clip_image002clip_image003
clip_image004{
clip_image005
public:
clip_image006clip_image007   
virtual void g()clip_image004{ cout << "Base1::g" << endl;}
clip_image006clip_image007   
void g1()clip_image004{cout << "Base1::g1" << endl;}
clip_image008}
;
clip_image001
class Derived1 : public Base,public Base1
clip_image002clip_image003
clip_image004{
clip_image005
public:
clip_image006clip_image007   
virtual void f()clip_image004{ cout << "Derived1::f" << endl;}
clip_image006clip_image007   
virtual void h()clip_image004{ cout << "Derived1::h" << endl;}
clip_image008}
;
clip_image001
clip_image001
void Test1()
clip_image002clip_image003
clip_image004{
clip_image005
clip_image005   
//
对于单继承,
clip_image005    //
如果PD真的指向Derived,用dynamic_caststatic_cast效果相同
clip_image005
    Base *pD = new Derived;
clip_image005    Derived *pD1 = dynamic_cast<Derived*>(pD);
clip_image005    pD1->f();
clip_image005    pD1->k();
clip_image005    pD1->f1();
clip_image005
clip_image005    Derived *pD2 = static_cast<Derived*>(pD);
clip_image005    pD2->f();
clip_image005    pD2->k();
clip_image005    pD2->f1();
clip_image005
clip_image005
clip_image005   
// 但是如果PB不是真的指向Derived,则用dynamic_cast则返回NULL,能够更早的禁止error的发生,
clip_image005    //
如果用static_cast虽然返回的不为NULL,但是运行时可能抛出exception
clip_image006clip_image007
    /**///// Error code
clip_image005    //Base *pB = new Base();
clip_image005    //Derived *pD3 = static_cast<Derived*>(pB);
clip_image005    //pD3->f();
clip_image005    //pD3->k();
clip_image005    //pD3->f1();
clip_image005
clip_image005    //Derived *pD4 = dynamic_cast<Derived*>(pB);
clip_image005    //pD4->f();
clip_image005    //pD4->k();
clip_image005    //pD4->f1();
clip_image008
}
clip_image001
clip_image001
void Test2()
clip_image002clip_image003
clip_image004{
clip_image005   
//
对于多重继承,
clip_image005    //
如果PD真的指向的是Derived1,使用dynamic_caststatic_cast都可以转化为Derived1
clip_image005    //
但是如果要转化为Base的兄弟类Base1,必须使用dynamic_cast,使用static_cast不能编译。
clip_image005
    Base *pD = new Derived1;
clip_image005    Derived1 *pD1 = dynamic_cast<Derived1*>(pD);
clip_image005    pD1->f();
clip_image005    pD1->h();
clip_image005    pD1->f1();
clip_image005
clip_image005    Base1 *pB1 = dynamic_cast<Base1*>(pD);
clip_image005    pB1->g();
clip_image005
clip_image005    Derived1 *pD2 = static_cast<Derived1*>(pD);
clip_image005    pD2->f();
clip_image005    pD1->h();
clip_image005    pD2->f1();
clip_image005
clip_image006clip_image007    /**/
//// error can not compiler
clip_image005    //Base1 *pB2 = static_cast<Base1*>(pD);
clip_image005    //pB2->g();
clip_image005
clip_image005    //
当然对于PB不是真的指向Derived1,想要转化为Derived1Base的兄弟类Base1,情况与Test1中的error情况相同。
clip_image005

clip_image005
clip_image008}

clip_image001
clip_image001
int _tmain(int argc, _TCHAR* argv[])
clip_image002clip_image003
clip_image004{
clip_image005    Test1();
clip_image005
clip_image005    Test2();
clip_image005
clip_image005   
return 0;
clip_image008}

clip_image001
clip_image001


三 结论

大家先总结下,哈哈!

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

clip_image009

评论

# 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的指针,所以这时pd3basef f1 的调用是成功的(返回当然是base::f base::f1了)。只是在调用K时失败。
个人理解:动态转换其实是一个类家族的安全检查和公共界面问题,上面例子知道了一个类的父类的时候,看上去没有什么用,你把dynamicbase *都去掉,直接new derived ,结果还是一样的。有时在不知道父类时或者不确定你的类是否是父类的override时,你在想用这种公共界面,为了类型安全(也就是确定他们是一个家族中的类),就要用到这种强制转换
说的不好的,望大家指出,一起讨论  回复  更多评论   

 

posted on 2011-05-04 15:08 肥仔 阅读(950) 评论(0)  编辑 收藏 引用 所属分类: C++ 基础


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理