2010-10-01 10 views
35

Siempre pienso en tener que usar punteros para el polimorfismo. Usando el ejemplo canónico:¿Las referencias y punteros son iguales con respecto al polimorfismo?

DrawEngine::render(Shape *shape) 
{ 
    shape->draw(); 
    shape->visible(true); 
} 

Y pasando en puntero a varias clases derivadas de Shape. ¿Funciona igual con referencias?

DrawEngine::render(Shape &shape) 
{ 
    shape.draw(); 
    shape.visible(true); 
} 

siquiera es válida para hacerlo:

engine.render(myTriangle); // myTriangle instance of class derived from Shape 

Si esto funciona, ¿hay alguna diferencia entre los dos casos? Traté de encontrar información en Stroustrup, pero no encontré nada.

Volví a abrir esto porque quería explorar un poco más.

De modo que al menos una diferencia es dynamic_cast. Para mí, el polimorfismo incluye el uso de dynamic_cast.

¿Puedo ir

Rhomboid & r = dynamic_cast<Rhomboid &>(shape); 

¿Qué ocurre si falla el elenco? ¿Esto es diferente?

Rhomboid * r = dynamic_cast<Rhomboid*>(&shape); 

Respuesta

38

Con respecto al polimorfismo, las referencias funcionan igual que los punteros.

+2

@ PM100:. Directamente, sin duda, pero hay diferentes facetas. Por ejemplo, 'dynamic_cast' lanzará una excepción en lugar de devolver null en un mal lanzamiento. – GManNickG

+2

@GMan: Pienso en el ejemplo 'dynamic_cast' como diferencia básica entre punteros y referencias: los punteros pueden ser legalmente NULL, mientras que las referencias no. El corazón de la pregunta, mientras lo leo, es si las referencias se comportan igual con respecto a las tablas virtuales. De ahí la breve respuesta. –

+1

De la forma en que lo veo, las referencias parecen ser poco más que azúcar sintáctico sobre punteros. –

0

Los punteros ayudan de otras maneras también. Como pasar una cadena y aceptarlo como parámetro char * en una función.

Considere el ejemplo de edad revirtiendo una secuencia en el lugar: Código

void reversestring(char* myString) 
{ 
int firstPos=0; 
int lastPos=myString.length - 1; 
while (firstPos < lastPos) 
{ 
    char temp=myString[firstPos]; 
    myString[firstPos]=myString[lastPos]; 
    myString[lastPos]=temp; 
    firstPos++; 
    lastPos--; 
} 
} 

escritura para la manipulación de cadenas como estas utilizando referencias no será tan sencillo.

+0

myString.length?¿Eso es C++? –

+1

@TheLightSpark Sería válido si 'myString' fuera un' std :: string', pero creo que no es válido para una cadena C en bruto. Además, 'length' debería ser una llamada a la función, pero eso es quisquilloso. –

7

Con respecto a dynamic_cast, un modelo fallido produce un nullpointer con punteros y da como resultado un lanzamiento de una excepción bad_cast (IIRC) con referencias.

Una razón es que no existe una referencia nula válida.

Y posiblemente otra razón (pero podría ser una característica emergente involuntariamente útil) es que a veces uno necesita la excepción y a veces uno necesita el nullpointer fácil de verificar, y no importa si tiene una referencia o un puntero en De la mano se necesita como máximo un operador de desreferenciación o dirección para obtener el comportamiento que desea.

Saludos & HTH,

Cuestiones relacionadas