Understanding Dynamic_cast in C++

在面向对象程序设计中,有时咱们须要在运行时查询一个对象是否能做为某种多态类型使用。与Java的instanceof,以及C#的as、is运算符相似,C++提供了dynamic_cast函数用于动态转型。相比C风格的强制类型转换和C++ reinterpret_castdynamic_cast提供了类型安全检查,是一种基于能力查询(Capability Query)的转换,因此在多态类型间进行转换更提倡采用dynamic_cast。本文主要介绍dynamic_cast的意义,用法和注意事项。安全

基本用法函数

dynamic_cast能够获取目标对象的引用或指针:设计

T1 obj;
T2* pObj = dynamic_cast<T2*>(&obj);     //转换为T2指针,失败返回NULL
T2& refObj = dynamic_cast<T2&>(obj);    //转换为T2引用,失败抛出bad_cast异常

多态类型指针

在使用时须要注意:被转换对象obj的类型T1必须是多态类型,即T1必须公有继承自其它类,或者T1拥有虚函数(继承或自定义)。若T1为非多态类型,使用dynamic_cast会报编译错误。下面的例子说明了哪些类属于多态类型,哪些类不是:code

//A为非多态类型 
class A{
};

//B为多态类型
class B{ 
    public: virtual ~B(){}
};

//D为多态类型
class D: public A{
};

//E为非多态类型
class E : private A{
};

//F为多态类型
class F : private B{
};

横向转型对象

在多态类型间转换,分为3种类型:
1.子类向基类的向上转型(Up Cast)
2.基类向子类的向下转型(Down Cast)
3.横向转型(Cross Cast)继承

向上转型是多态的基础,需不要借助任何特殊的方法,只需用将子类的指针或引用赋给基类的指针或引用便可,固然dynamic_cast也支持向上转型,而其老是确定成功的。而对于向下转型和横向转型来说,其实对于dynamic_cast并无任何区别,它们都属于能力查询。为了理解方便,咱们不妨把dynamic_cast视为cross cast:it

class Shape {
    public: virtual ~Shape();
    virtual void draw() const = 0;
};

class Rollable {
    public: virtual ~Rollable();
    virtual void roll() = 0;
};

class Circle : public Shape, public Rollable {
    void draw() const;
    void roll();
};

class Square : public Shape {
    void draw() const;
};

//横向转型失败
Shape *pShape1 = new Square();
Rollable *pRollable1 = dynamic_cast<Rollable*>(pShape2);//pRollable为NULL

//横向转型成功
Shape *pShape2 = new Circle();
Rollable *pRollable2 = dynamic_cast<Rollable*>(pShape2);//pRollable不为NULL

指针比较编译

接上面的例子,在个人机器上pShape2pRollable2的值(所指向的地址)分别为: pShape2: 0x0039A294, pRollable2:0x0039A290ast

说明dynamic_cast在进行转型的时候对不一样多态类型设置了不一样的偏移量。接下来的问题是 pRollable2 == pShape2

相关文章
相关标签/搜索