2010-03-28 17 views
11

En cuanto a lo siguiente programa en C++:Conversión de puntero a puntero entre las clases derivadas y de base?

class Base { }; 

class Child : public Base { }; 

int main() 
{ 
    // Normal: using child as base is allowed 
    Child *c = new Child(); 
    Base *b = c; 

    // Double pointers: apparently can't use Child** as Base** 
    Child **cc = &c; 
    Base **bb = cc; 

    return 0; 
} 

GCC produce el siguiente error en la última instrucción de asignación:

error: invalid conversion from ‘Child**’ to ‘Base**’ 

Mi pregunta es en dos partes:

  1. Por qué no hay Conversión implícita de Child ** a Base **?
  2. Puedo hacer que este ejemplo funcione con un molde de estilo C o reinterpret_cast. Usar estos moldes significa tirar todo tipo de seguridad. ¿Hay algo que pueda agregar a las definiciones de clase para hacer estos punteros emitidos implícitamente, o al menos expresar la conversión de una manera que me permita usar static_cast?
+0

Las variaciones en esta pregunta en muchos lenguajes de programación son una de las preguntas más comunes sobre SO. Pero todos lo formulan de forma ligeramente diferente incluso para el mismo idioma, por lo que encontrar duplicados puede ser difícil. –

+0

"Reparar" este ejemplo para evitar la aparición de sombreados dependerá del motivo por el que está utilizando un puntero a puntero en primer lugar. – aschepler

Respuesta

19

Si esto era permitido, se podría escribir esto:

*bb = new Base; 

Y c terminaría apunta a una instancia de Base. Malo.

+0

Pequeña corrección: podría decir '** bb = new Base();' Just '* bb' no estaría permitido. – Phil

+4

@Phil: 'new' devuelve un puntero, que es tipo' * Base'. 'bb' es del tipo' ** Base'. Por lo tanto, '* bb' es el nivel correcto de desreferencia. – Amber

+1

El fundamento es esencialmente el mismo que el comp.lan.gc Preguntas frecuentes sobre la no equivalencia de 'char **' y 'char const **': http://c-faq.com/ansi/constmismatch.html –

Cuestiones relacionadas