Construção usada deliberadamente para converter um tipo
Alternativas
- Casting de tipos
- Funções de conversão e wrappers
Exemplo de casting de tipo em C
int i = (int)f;
veiculo *v = (veiculo*)apontador;
Exemplo com pseudofunções de conversão em Ada
n : inteiro;
r : real;
r := 10.4;
n := inteiro(r);
r := real(n);
Em R
var = "12.34"
i = as.numeric(var)
- São estruturalmente equivalentes
- Mesma representação de baixo nível
- Exemplo: duas
struct
com mesmos campos - Conversão é trivial
- Tipos tem domínios diferentes, mas mesma intersecção
- Exemplo: tipo inteiro com sinal, outro sem sinal
- Código necessário para fazer a conversão
- Verificar dinamicamente se a conversão é válida
- Se falha, um erro semântico de execução é lançado
- Se funciona, mesma representação é utilizada
- Tipos tem diferentes representações de baixo nível
- Hipótese: podemos definir uma função de correspondência
- Normalmente com suporte de hardware
Linguagem permite testar dinamicamente o tipo do objeto
Objective-C
BOOL b = [objeto isKindOfClass: [NSString class]];
Java
bool b = p instanceof NomeDaClasse;
Por funções de conversão (Pascal, ML)
var n, m: Integer; x: Real;
...
n := Round(x);
m := Trunc(x);
Por uso de wrappers (Java)
int a = 10;
Integer b;
b = new Integer(a);
a = b.intValue();
Utilizado para manipular blocos de memória
- Alocados dinamicamente
- Lidos de um arquivo em formato binário (raw)
Exemplos em C
void *memoria_alocada = malloc(1000);
char *minha_str = (char*)memoria_alocada;
void *block = malloc(100);
read(fd, block, 100);
Record *header = (Record*)bloco;
Programador decide pelo tipo de cast
Melhora a legibilidade do código
\pause dynamic_cast<tipo>(valorParaConversao)
- Compilador embute código de checagem; pode retornar NULL
\pause const_cast<tipo>(valorParaConversao)
- Permite remover o atributo constante de uma variável
- Exemplo
const_cast<MinhaClasse*>(this)->valor = 41;
static_cast<tipo>(valorParaConversao)
- Troca a interpretação do valor; segurança questionável
- Exemplo
int* a = new int(); void* b = static_cast<void*>(a); int* c = static_cast<int*>(b);
- Todos apontam para o mesmo endereço
reinterpret_cast<tipo>(valorParaConversao)
- Utilizado em duplas para garantir semântica
- Exemplo
int* a = new int(); void* b = reinterpret_cast<void*>(a); int* c = reinterpret_cast<int*>(b);
- a e c tem o mesmo valor
- Mas o valor de b não é definido
https://stackoverflow.com/questions/573294/when-to-use-reinterpret-cast
Paradigma OO: Hierarquia de classes
Upcasting
- Sem restrições, sempre funciona
Downcasting
- Pode não funcionar
- Ambiente de execução tem que estar preparado
Exemplo em Java – upcasting.java
Coerção cada vez menos presente
Mecanismos de conversão explícita se multiplicam
- em LPs compiladas