Pregunta

he definido una interfaz Cloneable:

struct Cloneable
{
  virtual Cloneable * clone(void) const = 0;
}

Tengo también algunas otras clases de interfaz (contenido no es relevante para emisión):

struct Interface
{
};

struct Useful_Goodies
{
};

He creado un objeto hoja que hereda de las clases anteriores:

struct Leaf : public Cloneable, public Interface, public Useful_Goodies
{
  Leaf * clone(void) const  // Line #1 for discussion.
  {
     return new Leaf(*this);
  }
};

Estoy recibiendo el error:

overriding virtual function return type differs and is not covariant from 'Cloneable::clone'

Si cambio el tipo de Cloneable *, me sale este mensaje de error:

'return' : ambiguous conversions from 'Leaf *' to 'Cloneable *'

Mis Preguntas (todos relacionados):

  1. ¿Cómo puede resolver la clase hoja de la requisitos de la Cloneable interfaz?
  2. ¿Hay una mejor solución para implementar una La clonación de contrato, donde todos los objetos están garantizados para poner en práctica la clonación?

Estoy usando este paradigma como parte de la programación genérica (registros, campos y base de datos).

Compilador: MS Visual Studio 2008; Plataformas: Windows XP y Vista

¿Fue útil?

Solución

Tener su retorno de la función clone un Cloneable * es correcta.

Se obtendrá una conversión ambigua si uno de sus interfaces de deriva también de Cloneable.

Editar Alf señala en los comentarios que no sólo es posible para Leaf::clone para devolver una Leaf*, en realidad es preferible que lo haga. Mi error.

Otros consejos

Es probable que no se menciona que Interface o alguna otra clase de base también Cloneable hereda. Los medios "conversión" ambigua Leaf probablemente contiene múltiples sub-objetos de la clase base Cloneable. (Un problema con el tipo de devolución covariante podría ser un resultado directo del mismo problema.)

Usted querrá resolver este problema utilizando virtuales herencia (recomendada y vinculado lectura: temas de C ++ FAQ Lite 25.8 través 25.13). Para empezar, el cambio todos casos de : public Cloneable a : public virtual Cloneable.

puedo arriesgar y decir que usted está probablemente no virtualmente heredando de Cloneable de más de un camino. Es decir, algo de su otra base, además de los hereda Cloneable directos (directa o indirectamente) de Cloneable. Esto hace que la conversión de Leaf* a Cloneable* ambigua, ya que hay más de una base Cloneable en su Leaf.

La solución simple es utilizar la herencia virtual a partir de la interfaz:

struct Cloneable {
   virtual Cloneable * clone() = 0;
};
struct Interface : virtual Cloneable {
};
struct Test : virtual Cloneable, Interface {
   virtual Test* clone() {
      return new Test(*this);
   }
};

medios herencia virtual que incluso si ambos Interface y Test Heredar del Cloneable, sólo hay un único objeto base Cloneable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top