1261 votos

Cuando debe static_cast, dynamic_cast, const_cast y reinterpret_cast ser utilizado?

¿Cuáles son los usos adecuados de:

  • static_cast
  • dynamic_cast
  • const_cast
  • reinterpret_cast
  • C-estilo de fundición (type)value
  • La función de estilo de fundición type(value)

y ¿cómo decidir cuál utilizar en cada caso?

1540voto

coppro Puntos 10692

static_cast es el modelo en primer lugar, usted debe tratar de usar. Hace las cosas como las conversiones implícitas entre tipos (int, float, o un puntero a void*), y también puede llamar a las funciones de conversión explícita (o implícito). En muchos casos, indicando expresamente static_cast no es necesario, pero es importante tener en cuenta que el T(something) sintaxis es equivalente a (T)something y debe ser evitado (más sobre esto más adelante). Un T(something, something_else) es seguro, sin embargo, y garantizado para llamar al constructor.

static_cast puede lanzar a través de las jerarquías de herencia. Es innecesario cuando se lanza hacia arriba (hacia una clase base), pero cuando se lanza hacia abajo puede ser utilizado como siempre y como no emitidos a través de virtual de la herencia. No hacer la comprobación, sin embargo, y es un comportamiento indefinido a static_cast hacia abajo en una jerarquía a un tipo que no es realmente el tipo de objeto.


const_cast puede ser utilizado para eliminar o agregar const a una variable; no hay otro C++ fundido es capaz de quitar (ni siquiera reinterpret_cast). Es importante tener en cuenta que la modificación de una antigua const valor sólo es indefinido si la variable original es de const; si se usa para tomar la const fuera de una referencia a algo que no declarada con const, es seguro. Esto puede ser útil cuando la sobrecarga de funciones miembro basa en const, por ejemplo. También puede ser utilizado para agregar const a un objeto, como para llamar a un miembro de la función de sobrecarga.

const_cast también funciona de manera similar en volatile, a pesar de que es menos común.


dynamic_cast se utiliza casi exclusivamente para el manejo de polimorfismo. Se puede convertir un puntero o una referencia a cualquier polimórficos tipo a cualquier otro tipo de clase (un polimorfo tipo tiene al menos una función virtual, declarada o heredado). Usted puede utilizarlo para algo más que para fundición a la baja, usted puede lanzar hacia los lados o incluso a otro de la cadena. La dynamic_cast va a buscar el objeto deseado y volver a hacerlo si es posible. Si no, se volverá NULL en el caso de un puntero, o tirar std::bad_cast en el caso de una referencia.

dynamic_cast tiene algunas limitaciones, sin embargo. No funciona si hay varios objetos del mismo tipo en la jerarquía de herencia (el llamado 'temido de diamante') y no está utilizando virtual de la herencia. También se puede ir sólo a través de la herencia pública será siempre fallan a viajar a través de protected o private de la herencia. Esto rara vez es un problema, sin embargo, como tales formas de herencia son raros.


reinterpret_cast es la más peligrosa de fundición, y debe ser usada con moderación. Resulta que un tipo directamente a otra - tales como la fundición, el valor de un puntero a otro, o para almacenar un puntero en un int, o todo tipo de cosas desagradables. En gran medida, la única garantía de que usted consigue con reinterpret_cast es que normalmente si lanzas el resultado para el tipo de original, obtendrá el mismo valor exacto (pero no se si el tipo intermedio es menor que el tipo de original). Hay un número de conversiones que reinterpret_cast no puede hacer, también. Se utiliza principalmente para particularmente extraño conversiones de bits y manipulaciones, como convertir un raw flujo de datos en datos reales, o el almacenamiento de datos en los bits bajos de un alineados puntero.


C casts son los yesos utilizando (type)object o type(object). Un estilo C elenco se define como la primera de la siguiente, que tiene éxito:

  • const_cast
  • static_cast (a pesar de ignorar las restricciones de acceso)
  • static_cast (ver arriba), a continuación, const_cast
  • reinterpret_cast
  • reinterpret_cast, a continuación, const_cast

Por lo tanto, puede ser utilizado como sustituto de otros elencos, en algunos casos, pero puede ser extremadamente peligroso debido a la posibilidad de recaer en un reinterpret_cast, y el segundo debe ser preferido al momento de la conversión explícita es necesaria, a menos que esté seguro static_cast tendrá éxito o reinterpret_cast fallará. Incluso entonces, considerar el más largo, el más explícito opción.

C-estilo arroja también ignoran el control de acceso cuando se realiza una static_cast, lo que significa que tienen la capacidad de llevar a cabo una operación que ningún otro elenco puede. Este es principalmente un parche, sin embargo, y en mi mente es sólo otra razón para evitar el C-estilo de moldes.

159voto

Fred Larson Puntos 27404

Uso dynamic_cast para la conversión de punteros o referencias dentro de una jerarquía de herencia.

Uso static_cast para el común de las conversiones de tipo.

Uso reinterpret_cast bajo nivel de la reinterpretación de los patrones de bits. Utilizar con extrema precaución.

Uso const_cast de arrojando const/volatile. Evitar esto a menos que usted está atascado el uso de un const-incorrecta de la API.

62voto

Sumit Arora Puntos 196

(Una gran cantidad de teóricos y conceptuales explicación ha sido dada de arriba)

A continuación son algunos de los ejemplos prácticos cuando he usado static_cast, dynamic_cast ,const_cast ,reinterpret_cast.

(También se refiere esto para entender la explicación : http://www.cplusplus.com/doc/tutorial/typecasting/)

estática reparto :

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)
{
    // typecasting the message data based on the message type
    switch (msg->message_id)
    {
        case MSG_DEBUG_OUT:
        {
            DebugMsgData *data = dynamic_cast<DebugMsgData*>(msg->pdata);
                }

            case MSG_XYZ:
        {
            XYZMsgData *data = dynamic_cast<XYZMsgData*>(msg->pdata);
             }
         .....
         }
}

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;

// Lee Bytes de que los retornos de 2 bytes consiguió leer.

bool ByteBuffer::ReadUInt16(uint16& val) {
  return ReadBytes(reinterpret_cast<char*>(&val), 2);
}

9voto

andreas buykx Puntos 4710

¿ Esto responde a tu pregunta?

Nunca he usado reinterpret_cast, y se preguntan si la ejecución en un caso que necesita no es un olor de un mal diseño. En la base de código de trabajo en dynamic_cast se utiliza mucho. La diferencia con static_cast es que un dynamic_cast ¿el tiempo de ejecución de la comprobación que se puede (seguro) o no (más gastos) de lo que uno desea (vea msdn).

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X