C++ dynamic_cast

【格式】
dynamic_cast < type-id > (expression)
该运算符把expression转换成type-id类型的对象。Type-id可以是类的指针、类的引用或者void*。如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。

【作用】
将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理, 即会作出一定的判断。
若对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;
若对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。

【注意】:
1、dynamic_cast在将父类cast到子类时,父类必须要有虚函数(因为当类没有虚函数表的时候,dynamic_cast就不能用RTTI来确定类的具体类型,于是就直接不通过编译。),否则编译器会报错。
2、 dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换(子到父)时,dynamic_cast和static_cast的效果是一样的;
在进行下行转换时(父到子),dynamic_cast具有类型检查的功能,比static_cast更安全。**


#include <iostream>
#include <assert.h>

using namespace std;

// 我是父类
class Tfather
{
public:
    virtual void f() { cout << "father's f()" << endl; }
};

// 我是子类
class Tson : public Tfather
{
public:
    void f() { cout << "son's f()" << endl; }

    int data; // 我是子类独有成员
};

int main()
{ 
    Tfather father;
    Tson son;
    son.data = 123;

    Tfather *pf;
    Tson *ps;

    /* 上行转换:没有问题,多态有效 */
    ps = &son;
    pf = dynamic_cast<Tfather *>(ps);
    pf->f();

    /* 下行转换(pf实际指向子类对象):没有问题 */
    pf = &son;
    ps = dynamic_cast<Tson *>(pf);
    ps->f();
    cout << ps->data << endl;        // 访问子类独有成员有效

    /* 下行转换(pf实际指向父类对象):含有不安全操作,dynamic_cast发挥作用返回NULL */
    pf = &father;
    ps = dynamic_cast<Tson *>(pf);
    assert(ps != NULL);             // 违背断言,阻止以下不安全操作
    ps->f();
    cout << ps->data << endl;        // 不安全操作,对象实例根本没有data成员

    /* 下行转换(pf实际指向父类对象):含有不安全操作,static_cast无视 */
    pf = &father;
    ps = static_cast<Tson *>(pf);
    assert(ps != NULL);
    ps->f();
    cout << ps->data << endl;        // 不安全操作,对象实例根本没有data成员

    system("pause");
}

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部