Qual é a diferença entre static_cast <> e conversão de estilo C?

Respostas:

217

As conversões no estilo C ++ são verificadas pelo compilador. As conversões no estilo C não são e podem falhar no tempo de execução.

Além disso, as conversões no estilo c ++ podem ser pesquisadas com facilidade, enquanto é realmente difícil pesquisar as conversões no estilo c.

Outro grande benefício é que os quatro modelos diferentes de estilo C ++ expressam a intenção do programador de maneira mais clara.

Ao escrever C ++, eu sempre usaria os C ++ sobre o estilo C.

Glen
fonte
67
Os únicos lançamentos que podem falhar no tempo de execução são dynamic_casts.
R. Martinho Fernandes
12
O reinterpret_cast <T> (U) do C ++ pode falhar no tempo de execução da mesma maneira que as transmissões no estilo C, e todos eles são bem diferentes de como o dynamic_cast <T> (U) falha.
Christopher Smith
20
˗1 conversão C normal (int)somethingnão pode falhar - você é convertido para int ou erro do compilador.
Tomáš Zato - Restabelece Monica
2
Você pode explicar por que as conversões de C ++ são pesquisadas mais facilmente do que as de C?
Minh Tran #
3
@MinhTran Para o estilo C ++, você pode procurar a palavra-chave "cast" nos arquivos de origem. Mas o que você poderia fazer com os elencos em estilo c?
Huangzonghao 31/05
176

Em resumo :

  1. static_cast<>() dá a você a capacidade de verificar o tempo de compilação, o elenco do estilo C não.
  2. static_cast<>() é mais legível e pode ser detectado facilmente em qualquer lugar dentro de um código fonte C ++, C_Style cast is'nt.
  3. As intenções são transmitidas muito melhor usando conversões de C ++.

Mais explicações :

A conversão estática realiza conversões entre tipos compatíveis . É semelhante ao elenco do estilo C, mas é mais restritivo. Por exemplo, a conversão no estilo C permitiria que um ponteiro inteiro aponte para um caractere.

char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes

Como isso resulta em um ponteiro de 4 bytes (um ponteiro para um tipo de dados de 4 bytes) apontando para 1 byte de memória alocada, a gravação nesse ponteiro causará um erro em tempo de execução ou substituirá alguma memória adjacente.

*p = 5; // run-time error: stack corruption

Em contraste com a conversão no estilo C, a conversão estática permitirá que o compilador verifique se os tipos de dados de ponteiro e ponta são compatíveis, o que permite ao programador capturar essa atribuição incorreta de ponteiro durante a compilação.

int *q = static_cast<int*>(&c); // compile-time error

Você também pode verificar esta página para obter mais explicações sobre os lançamentos em C ++: Clique aqui

Breeze
fonte
17
Eu acho que em vez de "ponteiro de 4 bytes" você quis dizer "ponteiro para 4 bytes tipo de dados"
iheanyi
mas permite int q = static_cast <int> (c);
22419 TonyParker
3
@ TonyParker Isso é porque não há nada de errado com essa linha.
Braden Best
15

Consulte Uma comparação dos operadores de conversão de C ++ .

No entanto, o uso da mesma sintaxe para uma variedade de operações de conversão diferentes pode tornar clara a intenção do programador.

Além disso, pode ser difícil encontrar um tipo específico de conversão em uma grande base de código.

a generalidade do elenco do estilo C pode ser um exagero para situações em que tudo o que é necessário é uma simples conversão. A capacidade de selecionar entre vários operadores de fundição diferentes, com diferentes graus de potência, pode impedir que os programadores convertam inadvertidamente para um tipo incorreto.

Eugene Yokota
fonte
14
struct A {};
struct B : A {};
struct C {}; 

int main()
{
    A* a = new A;    

    int i = 10;

    a = (A*) (&i); // NO ERROR! FAIL!

    //a = static_cast<A*>(&i); ERROR! SMART!

    A* b = new B;

    B* b2 = static_cast<B*>(b); // NO ERROR! SMART!

    C* c = (C*)(b); // NO ERROR! FAIL!

    //C* c = static_cast<C*>(b); ERROR! SMART!
}
Rishi Khaneja
fonte
5
Você poderia elaborar mais sua resposta adicionando um pouco mais de descrição sobre a solução que você fornece?
Abarisone
1
Acho que a resposta mostra que "static_casts" verifica as conversões de tipo para garantir que elas estejam ao longo de caminhos válidos no gráfico da hierarquia. Neste exemplo em particular, a conversão de A * para B * ou B * para A * é permitida porque A e B formam um caminho no gráfico hierárquico. C * não está no caminho, portanto o static_cast produzirá um erro em tempo de compilação. Nota: Pode ser interessante notar que a conversão de A * para B * pode resultar em NULL com um dynamic_cast em tempo de execução, dependendo do verdadeiro objeto subjacente.
Tommy Chen
7

Um ótimo post explicando diferentes lançamentos em C / C ++ e o que o elenco em estilo C realmente faz: https://anteru.net/blog/2007/12/18/200/index.html

Conversão de estilo C, usando a sintaxe da variável (tipo). O pior já inventado. Isso tenta fazer as seguintes transmissões, nesta ordem: (consulte também C ++ Standard, 5.4 expr.cast no 5)

  1. const_cast
  2. static_cast
  3. static_cast seguido por const_cast
  4. reinterpret_cast
  5. reinterpret_castseguido por const_cast
Ying Xiong
fonte
5

static_castverifica no momento da compilação se a conversão não está entre tipos obviamente incompatíveis. Ao contrário dynamic_cast, nenhuma verificação de compatibilidade de tipos é feita em tempo de execução. Além disso, a static_castconversão não é necessariamente segura.

static_cast é usado para converter de ponteiro para classe base em ponteiro para classe derivada ou entre tipos nativos, como enum para int ou flutuar para int.

O usuário de static_castdeve garantir que a conversão seja segura.

A conversão no estilo C não executa nenhuma verificação, durante a compilação ou no tempo de execução.

Kiriloff
fonte
3

Como existem muitos tipos diferentes de transmissão, cada um com semântica diferente, o static_cast <> permite que você diga "Estou fazendo uma conversão legal de um tipo para outro", como de int para dobrar. Um elenco simples no estilo C pode significar muitas coisas. Você está escalando para cima / baixo? Você está reinterpretando um ponteiro?

Doug T.
fonte