谈谈C++的类型转换符 static_cast、dynamic_cast、const_cast、reinterpret_cast

一、C风格(C-style)强制类型转换

(T) expression // cast expression to be of type T

 

二、C++的几种类型转换符号

1. static_cast

用法:static_cast <type-id> ( expression

Remarks:No run-time type check is made to help ensure the safety of the conversion.

该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。

它主要有以下几种用法:

class A

{

public:

    virtual void load() {cout << "a" << endl;}

};

class B : public A

{

public:

    virtual void load() {cout << "b" << endl;}

};

class C : public A

{

public:

    virtual void load() {cout << "c" << endl;}

};

void Load(A* pa)

{

    pa->load();

 

    if (pa != NULL)

    {

        delete pa;

        pa = NULL;

    }

}

 

(1)用于类层次结构中积累和子类之间指针或引用的转换。

进行上行转换(将派生类指针转换成基类指针)时是安全的;

 

int _tmain(int argc, _TCHAR* argv[])

{

    B *pb = new B();

    A *pa = static_cast<A*>(pb); // 安全

    Load(pa);

    return 0;

}

运行结果:b

 

进行下行转换(将基类指针转换为派生类指针)时,由于没有动态类型检查,所以是不安全的。

int _tmain(int argc, _TCHAR* argv[])

{

    A *pa = new A();

    B *pb = static_cast<B*>(pa); // 不安全

    Load(pb);

 

    return 0;

}

运行结果:a

 

(2)用于基本数据之间的转换,如把int转换成char。这种转换的安全性需要开发人员来保证。

(3)把空指针转换成目标类型的空指针。

(4)把任何类型的表达式转换成void类型。

(5)static_cast不能去掉类型的const、volitale属性(但可以用const_cast转换符进行转换)

 

2. dynamic_cast

有条件转化,动态类型之间的转换,运行时会做类型安全检查(转换失败就会返回NULL)

(1)在类层次间践行上行转换时,dynamic_cast和static_cast的效果是一样的。

int _tmain(int argc, _TCHAR* argv[])

{

    B *pb = new B();

    A *pa = dynamic_cast<A*>(pb);

    if (pa != NULL)

        Load(pa);

    return 0;

}

运行结果:b

(2)在类层次间进行下行转换时,dynamic_cast具有类型检查的供能,比static_cast更安全。

 

int _tmain(int argc, _TCHAR* argv[])

{

    A* pa = new A();

    B* pb = dynamic_cast<B*>(pa);

    if (pb != NULL)

    {

        pb->load();

    }

    else

    {

        cout << "dynamic cast fail" << endl;

    }

 

    return 0;

}

运行结果:dynamic cast fail

 

3.reinterpret_cast

reinterpret_cast是为了映射到一个完全不同类型的意思,这个关键词在我们需要把类型映射回原有类型时用到它。我们映射到的类型仅仅是为了故弄玄虚和其他目的,这是所有映射中最危险的。static_cast 和 reinterpret_cast 操作符修改了操作数类型。它们不是互逆的; static_cast 在编译时使用类型信息执行转换,在转换执行必要的检测(诸如指针越界计算, 类型检查). 其操作数相对是安全的。另一方面;reinterpret _cast 仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换,例如:

int n=9; double d = static_cast < double > (n);

上面的例子中, 我们将一个变量从 int 转换到 double。 这些类型的二进制表达式是不同的。 要将整数 9 转换到 双精度整数 9,static_cast 需要正确地为双精度整数 d 补足比特位。其结果为 9.0。

 

float f = 19.2F; unsigned int *pa = reinterpret_cast<unsigned int*>(&f);

 

这次, 结果有所不同,在进行计算以后, *pa 包含无用值。这是因为 reinterpret_cast 仅仅是复制 f 的比特位到 *pa, 没有进行必要的分析。因此,我们要谨慎使用。

 

 

posted on 2011-03-14 17:42  Zhiqiang.Chen  阅读(173)  评论(0编辑  收藏  举报

导航