Você marcou isso com três idiomas e as respostas são muito diferentes entre os três. A discussão de C ++ implica mais ou menos na discussão de cast de C também, e isso dá (mais ou menos) uma quarta resposta.
Já que é aquele que você não mencionou explicitamente, começarei com C. Os casts de C têm vários problemas. Uma é que eles podem fazer uma série de coisas diferentes. Em alguns casos, o elenco não faz nada mais do que dizer ao compilador (em essência): "cala a boca, eu sei o que estou fazendo" - ou seja, ele garante que mesmo quando você fizer uma conversão que poderia causar problemas, o compilador não o avisará sobre esses problemas potenciais. Apenas por exemplo char a=(char)123456;
,. O resultado exato desta implementação definido (depende do tamanho e da assinatura dochar
) e, exceto em situações bastante estranhas, provavelmente não é útil. C casts também variam se são algo que acontece apenas em tempo de compilação (ou seja, você está apenas dizendo ao compilador como interpretar / tratar alguns dados) ou algo que acontece em tempo de execução (por exemplo, uma conversão real de duplo para longo).
C ++ tenta lidar com isso, pelo menos até certo ponto, adicionando um número de "novos" operadores de conversão, cada um dos quais é restrito a apenas um subconjunto dos recursos de uma conversão C. Isso torna mais difícil (por exemplo) fazer acidentalmente uma conversão que você realmente não pretendia - se você apenas pretende jogar fora a constância em um objeto, você pode usar const_cast
e ter certeza de que a única coisa que pode afetar é se um objecto é const
, volatile
ou não. Por outro lado, um static_cast
não pode afetar se um objeto é const
ouvolatile
. Resumindo, você tem a maioria dos mesmos tipos de recursos, mas eles são categorizados de forma que um elenco geralmente pode fazer apenas um tipo de conversão, onde um único elenco de estilo C pode fazer duas ou três conversões em uma operação. A principal exceção é que você pode usar um dynamic_cast
no lugar de static_cast
em pelo menos alguns casos e, apesar de ter sido escrito como um dynamic_cast
, na verdade terminará como um static_cast
. Por exemplo, você pode usar dynamic_cast
para percorrer uma hierarquia de classes para cima ou para baixo - mas um elenco "para cima" na hierarquia é sempre seguro, portanto, pode ser feito estaticamente, enquanto um elenco "para baixo" na hierarquia não é necessariamente seguro, por isso é feito dinamicamente.
Java e C # são muito mais semelhantes entre si. Em particular, com ambos a conversão é (virtualmente?) Sempre uma operação em tempo de execução. Em termos de operadores de cast C ++, geralmente é o mais próximo de a dynamic_cast
em termos do que realmente é feito - ou seja, quando você tenta converter um objeto para algum tipo de destino, o compilador insere uma verificação em tempo de execução para ver se a conversão é permitida e lançar uma exceção se não for. Os detalhes exatos (por exemplo, o nome usado para a exceção de "elenco incorreto") variam, mas o princípio básico permanece basicamente semelhante (embora, se a memória não for suficiente, Java faz casts aplicados a alguns tipos de não-objeto, como int
muito mais perto de C casts - mas esses tipos raramente são usados o suficiente para 1) Não me lembro com certeza e 2) mesmo que seja verdade, não importa muito de qualquer maneira).
Olhando para as coisas de forma mais geral, a situação é bastante simples (pelo menos IMO): um elenco (obviamente o suficiente) significa que você está convertendo algo de um tipo para outro. Quando / se você fizer isso, surge a pergunta "Por quê?" Se você realmente quer que algo seja um tipo específico, por que não definiu como esse tipo para começar? Isso não quer dizer que nunca haja uma razão para fazer tal conversão, mas sempre que isso acontecer, deve perguntar se você poderia redesenhar o código para que o tipo correto fosse usado em todo o processo. Mesmo conversões aparentemente inócuas (por exemplo, entre número inteiro e ponto flutuante) devem ser examinadas muito mais de perto do que é comum. Apesar de sua aparênciasimilaridade, inteiros deveriam realmente ser usados para tipos de coisas "contados" e ponto flutuante para tipos de coisas "medidos". Ignorar a distinção é o que leva a algumas das afirmações malucas como "a família americana média tem 1,8 filhos". Embora todos possamos ver como isso acontece, o fato é que nenhuma família tem 1,8 filhos. Eles podem ter 1 ou 2 ou mais do que isso - mas nunca 1.8.