跳转至

关于四种 Cast 的总结

dynamic_cast

1
dynamic_cast < type-id > ( expression )

      托管代码中的 dynamic_cast 行为有两项中断性变更:

  • 对指向装箱枚举的基础类型的指针的 dynamic_cast 将在运行时失败,返回 0 而不是转换后的指针。

  • 当type-id 是指向值类型的内部指针时,dynamic_cast 将不再引发异常;相反,强制转换在运行时失败。 强制转换返回 0 个针值,而不是引发。

Example

主要是使用dynamic_cast进行安全的向下转换(由基类至派生类),且对象为指针或引用,因为向上转换总是安全的。在向下转换不安全时返回空指针。 注意如果继承存在歧义,如:
Base->A
Base->B
C:A,B
则其在 C *tmp=dynamic_cast(Base * expression)时,会不知道从C:A还是C:B而发生问题。该问题可以通过增加强制类型转换限制路径解决。如:

    class A {virtual void f();};
    class B : public A {virtual void f();};
    class C : public A {virtual void f();};
    class D : public B, public C {virtual void f();};

    void f() {
    D* pd = new D;
    A* pa = dynamic_cast<A*>(pd);   // C4540, ambiguous cast fails at runtime
    B* pb = dynamic_cast<B*>(pd);   // first cast to B
    A* pa2 = dynamic_cast<A*>(pb);   // ok: unambiguous
    }

static_cast

1
static_cast < type-id > ( expression )
  • 使用方法和dynamic_cast相似。不过要为注意的是,static_cast并不会进行类型检查。
  • static_cast可以进行数值类型之间的转换,如int->char。但由于二者占位byte不同,需要程序员来验证 static_cast 转换的结果是否安全。
  • static_cast 运算符将空指针值转换为目标类型的空指针值。

  • 任何表达式都可以通过 static_cast运算符显式转换为 void 类型。 目标 void 类型可以选择性地包含 const、volatile 或 __unaligned 特性。

  • static_cast 运算符无法强制转换掉 const、volatile 或 __unaligned 特性。

const_cast

1
const_cast < type-id > ( expression )
  • 作用:从某个类删除 const、volatile 和 __unaligned 属性。
Example

需要注意的是,const修饰的函数,本质上是对this指针进行了如同 const class * pointer的修饰。所以pointer指向的对象按理无法被进行更改的。

    // expre_const_cast_Operator.cpp
    // compile with: /EHsc
    #include <iostream>

    using namespace std;
    class CCTest {
    public:
    void setNumber( int );
    void printNumber() const;
    private:
    int number;
    };

    void CCTest::setNumber( int num ) { number = num; }

    void CCTest::printNumber() const {
    cout << "\nBefore: " << number;
    const_cast< CCTest * >( this )->number--;
    cout << "\nAfter: " << number;
    }

    int main() {
    CCTest X;
    X.setNumber( 8 );
    X.printNumber();
    }

reinterpret_cast

1
reinterpret_cast < type-id > ( expression )
  • 滥用 reinterpret_cast 运算符可能很容易带来风险。 除非所需转换本身是低级别的,否则应使用其他强制转换运算符之一。

  • reinterpret_cast 运算符可用于 char 到 int 或 One_class 到 Unrelated_class 之类的转换,这本身并不安全。

  • reinterpret_cast 的结果不能安全地用于除强制转换回其原始类型以外的任何用途。 在最好的情况下,其他用途也是不可移植的。

  • reinterpret_cast 运算符无法强制转换掉 const、volatile 或 __unaligned 特性。 有关移除这些特性的详细信息,请参阅 const_cast Operator。

  • reinterpret_cast 运算符将空指针值转换为目标类型的空指针值。

  • reinterpret_cast 的一个实际用途是在哈希函数中,即,通过让两个不同的值几乎不以相同的索引结尾的方式将值映射到索引。reinterpret_cast 允许将指针视为整数类型。 结果随后将按位移位并与自身进行“异或”运算以生成唯一的索引(具有唯一性的概率非常高)。 该索引随后被标准 C 样式强制转换截断为函数的返回类型。

EX
    #include <iostream>
    using namespace std;

    // Returns a hash code based on an address
    unsigned short Hash( void *p ) {
    unsigned int val = reinterpret_cast<unsigned int>( p );
    return ( unsigned short )( val ^ (val >> 16));
    }

    using namespace std;
    int main() {
    int a[20];
    for ( int i = 0; i < 20; i++ )
        cout << Hash( a + i ) << endl;
    }

    Output:
    64641
    64645
    64889
    64893
    64881
    64885
    64873
    64877
    64865
    64869
    64857
    64861
    64849
    64853
    64841
    64845
    64833
    64837
    64825
    64829