2011-05-13 16 views
5

Dado que A* pA; y B* pB;, ¿hay CUALQUIER diferencia entre piezas fundidas a continuación Tipo (consulta para todo el estilo C++ arroja):puntero typecasting con y sin referencia

pB = reinterpret_cast<B*>(pA);  // pointer 
pB = reinterpret_cast<B*&>(pA);  // pointer-reference 

Respuesta

5

Los dos son radicalmente diferentes, al menos en teoría (y posiblemente en unas pocas máquinas raras, en la práctica). El primero toma un puntero a A, y lo convierte en un puntero a B; en teoría, al menos, esto puede implicar cambios en el tamaño y la representación de . (De hecho, he trabajado en máquinas donde char* era más grande que int* dudo bastante que todavía existen tales máquinas, aunque tal vez en el mundo incrustado ...). La segunda es realmente el equivalente de *reinterpret_cast<B**>(&pA); es toma los bits en pA, y le dice al compilador que los interprete como a B*. Si el formato es diferente, mala suerte, y si el tamaño es diferente, es probable que solo acceda a parte de pA o acceda a la memoria que no es parte de pA.

Además, el primero es un valor r, el segundo es un valor. Por lo tanto, algo gustan:

++ reinterpret_cast<B*>(pA); 

es ilegal, pero:

++ reinterpret_cast<B*&>(pA); 

no lo es. Esta es una técnica útil para ofuscar el código y obtener punteros desalineados, punteros en el medio de los objetos u otros punteros que no se atreven a eliminar la referencia.

En general, se debe evitar el segundo formulario, pero existen raras excepciones .Posix garantiza que todos los punteros, incluidos los punteros a las funciones (pero no los punteros a los miembros — Posix especifica un C ABI, que no tiene punteros a los miembros), tienen el mismo tamaño y formato, , por lo que se garantiza que la segunda forma trabajo. Y es la única manera en que puede convertir legalmente al regresar void* por dlsym en un puntero a una función :

int (*pf)(int); 
reinterpret_cast<void*&>(pf) = dlsym(handle, "functionName"); 

(En C, escribiría:

int (*pf)(int); 
*(void**)(&pf) = dlsym(handle, "functionName"); 

, consulte la official specification). Tales trucos permiten las conversiones entre los tipos de puntero que no están permitidos de otra manera, pero depende de garantías adicionales no en la norma.

+0

¡Gran respuesta Jmaes! –

1

reinterpret_cast es definido por la implementación. Por lo tanto, en teoría los resultados pueden ser diferentes, pero en la práctica puede suponer que los resultados serán los mismos porque typeid(B*) es igual a typeid(B*&) => en realidad está emitiendo el mismo tipo en ambos casos.

0

Hay No diferencia.

pB = reinterpret_cast<B*>(pA);  // pointer 

está lanzando a un puntero del tipo B* y

pB = reinterpret_cast<B*&>(pA);  // pointer-reference 

está lanzando para hacer referencia a un puntero.

Nota: no existe el puntero a referencia.

+2

En su pregunta OP ya mencionó que el primero es un puntero y el segundo es una referencia al puntero. –

+0

@Mihran Hovsepyan: OP dijo 'Pointer-Reference', no existe tal cosa? Solo puede haber referencia al puntero. –

+2

'Pointer-reference' en inglés es lo mismo que' reference of pointer' y no 'pointer to reference'. –

0

No funcional diferencia en absoluto.

Obviamente hay una diferencia de mantenimiento si utiliza esta última variante. Sus compañeros pensarían que ha fumado algo. ;-)

Cuestiones relacionadas