C ++

什么是正确的用途:

  • static_cast
  • dynamic_cast
  • const_cast
  • reinterpret_cast
  • C风格演员(type)value
  • 函数式投射type(value)
  • 如何决定在哪些特定情况下使用哪一种?


    static_cast是您应该尝试使用的第一个演员。 它执行诸如类型之间的隐式转换(例如intfloatvoid* ),它也可以调用显式转换函数(或隐式转换函数)。 在许多情况下,明确指出static_cast不是必需的,但需要注意的是T(something)语法等同于(T)something ,应该避免(稍后会详述)。 一个T(something, something_else)是安全的,但是,并保证调用构造函数。

    static_cast也可以通过继承层次结构进行投射。 向上施放(朝向基类)是不必要的,但是当向下施放时,只要它不通过virtual继承来施放,就可以使用它。 然而,它并没有检查,而且它对于一个层次结构中的static_cast来说是未定义的行为,而不是实际上是该对象类型的类型。


    const_cast可以用来删除或添加const到一个变量; 没有其他C ++强制转换能够将其删除(甚至没有reinterpret_cast )。 重要的是要注意,如果原始变量是const ,修改以前的const值只是未定义的; 如果你使用它来将const引用到没有用const声明的东西,那么它是安全的。 例如,当基于const重载成员函数时,这会很有用。 它也可以用来为一个对象添加const ,比如调用成员函数的重载。

    const_castvolatile上也同样起作用,尽管这种情况不太常见。


    dynamic_cast几乎专门用于处理多态性。 您可以将指针或对任何多态类型的引用强制转换为任何其他类类型(多态类型至少具有一个声明或继承的虚函数)。 您可以使用它不仅仅是向下投掷 - 您可以侧身投掷,甚至可以投射另一个链条。 dynamic_cast将查找所需的对象并在可能的情况下返回它。 如果不能,它将在指针的情况下返回nullptr ,或者在引用的情况下抛出std::bad_cast

    dynamic_cast有一些限制。 如果在继承层次结构中存在多个相同类型的对象(所谓的“可怕钻石”)并且您没有使用virtual继承,则它不起作用。 它也只能通过公共继承 - 它总是不能通过protectedprivate继承。 然而,这很少是一个问题,因为这种继承形式很少见。


    reinterpret_cast是最危险的演员,应该非常谨慎地使用。 它将一种类型直接转换为另一种类型 - 例如将值从一个指针转换为另一个指针,或者将指针存储在int ,或者存储各种其他令人讨厌的东西。 在很大程度上,你唯一能把握的reinterpret_cast是,通常,如果你把结果返回到原来的类型,你会得到的值完全相同( 如果中间型比原来的类型更小)。 reinterpret_cast也无法进行多次转换。 它主要用于奇怪的转换和位操作,如将原始数据流转换为实际数据或将数据存储在对齐指针的低位中。


    C风格转换和函数风格转换分别使用(type)objecttype(object) 。 C风格演员被定义为以下第一个成功的演员:

  • const_cast
  • static_cast (尽管忽略访问限制)
  • static_cast (见上面),然后是const_cast
  • reinterpret_cast
  • reinterpret_cast ,然后是const_cast
  • 因此,在某些情况下,它可以用作其他演员的替代品,但由于能够分解为reinterpret_cast ,因此可能非常危险;如果需要显式演员,则应优先选择后者,除非您确定static_cast会成功或reinterpret_cast将失败。 即便如此,考虑更长,更明确的选择。

    C风格转换在执行static_cast时也会忽略访问控制,这意味着它们可以执行其他类型转换无法执行的操作。 不过,这主要是一个混乱,在我看来,这是避免C型演员阵营的另一个原因。


    使用dynamic_cast在继承层次结构内转换指针/引用。

    使用static_cast进行普通类型转换。

    使用reinterpret_cast进行位模式的低级重新解释。 谨慎使用。

    使用const_cast来转换const/volatile 。 避免这种情况,除非你使用常量不正确的API。


    (上面已经给出了很多理论和概念上的解释)

    以下是我使用static_castdynamic_castconst_castreinterpret_cast时的一些实际示例

    (也可以参考以理解说明:http://www.cplusplus.com/doc/tutorial/typecasting/)

    static_cast:

    OnEventData(void* pData)
    
    {
      ......
    
      //  pData is a void* pData, 
    
      //  EventData is a structure e.g. 
      //  typedef struct _EventData {
      //  std::string id;
      //  std:: string remote_id;
      //  } EventData;
    
      // On Some Situation a void pointer *pData
      // has been static_casted as 
      // EventData* pointer 
    
      EventData *evtdata = static_cast<EventData*>(pData);
      .....
    }
    

    dynamic_cast:

    void DebugLog::OnMessage(Message *msg)
    {
        static DebugMsgData *debug;
        static XYZMsgData *xyz;
    
        if(debug = dynamic_cast<DebugMsgData*>(msg->pdata)){
            // debug message
        }
        else if(xyz = dynamic_cast<XYZMsgData*>(msg->pdata)){
            // xyz message
        }
        else/* if( ... )*/{
            // ...
        }
    }
    

    const_cast:

    // *Passwd declared as a const
    
    const unsigned char *Passwd
    
    
    // on some situation it require to remove its constness
    
    const_cast<unsigned char*>(Passwd)
    

    reinterpret_cast:

    typedef unsigned short uint16;
    
    // Read Bytes returns that 2 bytes got read. 
    
    bool ByteBuffer::ReadUInt16(uint16& val) {
      return ReadBytes(reinterpret_cast<char*>(&val), 2);
    }
    
    链接地址: http://www.djcxy.com/p/749.html

    上一篇: c++

    下一篇: How can I refresh a page with jQuery?