2012-08-06 23 views
12

Quería saber por qué C++ no es compatible con la covarianza en parámetros como en el siguiente ejemplo o si hay una forma de lograrlo?C++ covarianza en los parámetros

class base { 
public: 
virtual base* func(base * ptr) { return new base(); } 
}; 

class derived : public base { 
public: 
virtual derived* func(derived * ptr) override { return new derived(); } //not allowed 
}; 
+3

Una pregunta más interesante sería por qué la contra-varianza en los argumentos no es compatible. –

Respuesta

10

El tipo de retorno es permisible desde derived hereda de base, pero el parámetro de función no puede trabajar - no todos los base casos será un derived también. ¿Qué se supone que ocurre en los casos en que se llama al func en un puntero a base con un parámetro que no es derived? La implementación más derivada no es invocable.

+6

Que viola el principio de sustitución de liskov. –

+0

¿Hay una solución? En Java/C# puede simplemente usar un molde, pero en C++, su objeto se cortará. – Winter

+0

@Winter no hay división a menos que pase por el valor (y pasar por valor sería raro con funciones polimórficas, que es la pregunta aquí). Pasar por el puntero (como en la pregunta) o reference/shared_ptr/unique_ptr funcionará y se convertirá sin cortes como con cualquier otro idioma de OO. La única pregunta es qué utilizar para garantizar la seguridad y ajustarse a la jerarquía de tipos, que se reduce a una elección entre dynamic_cast o static_cast y una severa advertencia a los usuarios para que no rompan el contrato no escrito que están imponiendo. Posiblemente quiera revisar sus decisiones de diseño. – Flexo