静态时使用哪一个

可能重复:
在将void *转换为任何内容时,我应该使用static_cast还是reinterpret_cast

通常,特别是在Win32编程中,它需要从一种不透明类型转换为另一种类型。 例如:

 HFONT font = cast_here<HFONT>( ::GetStockObject( SYSTEM_FONT ) );

static_cast和reinterpret_cast在这里都适用,并且具有完全相同的效果,因为HFONT是一个指向专门用于定义由GetStockObject()返回的HFONT和HGDIOBJ的虚拟结构体的指针,它是一个void *指针。

哪一个 - static_cast或reinterpret_cast - 更可取?


大家都注意到reinterpret_cast <>比static_cast <>更危险。
这是因为reinterpret_cast <>忽略了所有的类型信息,只是在没有任何实际处理的情况下分配一个新类型,因此所做的处理是实现定义的(尽管通常指针的位模式相同)。

每个人都没有提及的是reinterpret_cast <>是一种记录程序的手段。 它告诉某人阅读代码,我们必须妥协某些内容,结果导致了一个危险的表演,并且当您篡改此代码时要小心。

使用reinterpret_cast <>在代码中突出显示这些危险区域。

从void *投射时,没有类型信息可用于演员。
因此,您要么执行无效投射,要么投射回先前投射到void *的原始类型。 任何其他类型的演员都将以一些未定义的行为结束。

这是使用reinterpret_cast <>的最佳情况,因为标准保证了使用reinterpret_cast <>将指针转换为void *并返回到其原始类型将会起作用。 而通过使用reinterpret_cast <>,你指出了人类的后遗症,这里发生了不好的事情。


陈述演员阵容会有相同的影响是不正确的。 演员们做了两件完全不同的事情:

  • static_cast<T>(x)表示将表达式x转换为类型T
  • reinterpret_cast<T*>(&x)表示将内存位置'&x'解释为T *
  • 考虑以下:

    struct A1 { int a1; };
    struct A2 { int a2; };
    struct B : public A1, public A2 {};
    
    void foo (A1 * a1, A2 * a2)
    {
      B * b1_a1 = static_cast<B*> (a1);
      B * b2_a1 = reinterpret_cast<B*> (a1);
      B * b1_a2 = static_cast<B*> (a2);
      B * b2_a2 = reinterpret_cast<B*> (a2);
    
      std::cout << "b1_a1==b1_a2" << (b1_a1==b1_a2) << std::endl;
      std::cout << "b2_a1==b2_a2" << (b2_a1==b2_a2) << std::endl;
    }
    
    int main ()
    {
      B b;
      foo (&b, &b);
    }
    

    该程序产生以下输出:

    g++ -o t t.cc ; ./t
    b1_a1==b1_a2: 1
    b2_a1==b2_a2: 0
    

    这显示了从a2b2static_cast如何正确调整指针,使其指向b的开始,但reinterpret_cast没有。


    static_cast总是可取的,避免做reinterpret_cast s,除非绝对必要。

    reinterpret_cast是最不安全的演员。

    有关哪些演员应在何时使用的更多信息。

    链接地址: http://www.djcxy.com/p/28747.html

    上一篇: Which one to use when static

    下一篇: main() function with wrong signature gets called