Frage

Ich habe eine klonbar Schnittstelle definiert:

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

Ich habe auch einige andere Schnittstellenklassen (Inhalt nicht relevant Ausgabe):

struct Interface
{
};

struct Useful_Goodies
{
};

Ich habe ein Blatt Objekt, das erbt von den oben genannten Klassen erstellt:

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

Ich erhalte die Fehlermeldung:

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

Wenn ich den Typen Cloneable * ändern, ich diese Fehlermeldung:

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

Meine Fragen (alle miteinander verwandt):

  1. Wie kann die Blattklasse lösen die Anforderungen der Cloneable Schnittstelle?
  2. Gibt es eine bessere Lösung ein implementieren Cloning-Vertrag, in dem alle Objekte garantiert das Klonen implementieren?

Ich verwende dieses Paradigma als Teil der generischen Programmierung (Datensätze, Felder und Datenbank).

Compiler: MS Visual Studio 2008; Plattformen: Windows XP & Vista

War es hilfreich?

Lösung

Nachdem Sie Ihre clone Funktion Rückkehr ein Cloneable * korrekt ist.

Sie erhalten eine mehrdeutige Umwandlung erhalten, wenn einer Ihrer Schnittstellen auch von Cloneable ableitet.

Edit: Alf Punkte in den Kommentaren, die nicht nur ist es möglich, Leaf::clone eine Leaf* zurückzukehren, es ist eigentlich bevorzugt, es so zu tun. Ich stehe korrigiert.

Andere Tipps

Du hast versagt wahrscheinlich, dass Interface oder eine andere Basisklasse zu erwähnen, auch inherits Cloneable. Die „mehrdeutig Umwandlung“ bedeutet Leaf enthält wahrscheinlich mehr Cloneable Basisklasse Subobjekte. (Ein Problem bei kovarianten Rückgabetyp ein direktes Ergebnis des gleichen Problems sein könnte.)

Sie wollen dieses Problem lösen mit virtuellen Vererbung (empfohlen und verlinkt zu lesen: C ++ FAQ Lite Themen 25.8 bis 25.13). So starten Sie mit, ändern alle Instanzen von : public Cloneable zu : public virtual Cloneable.

kann ich riskieren und sagen, dass Sie wahrscheinlich nicht so gut wie von Cloneable erben von mehr als einen Weg. einige Ihrer anderen Basis neben dem direkten Cloneable inherits (direkt oder indirekt), das heißt, von Cloneable. Dies macht die Umwandlung von Leaf* mehrdeutig Cloneable* wie es mehr als eine Cloneable Basis in Ihrem Leaf sind.

Die einfache Lösung wird mit virtueller Vererbung von der Schnittstelle:

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

Virtuelle Vererbung bedeutet, dass selbst wenn beide Interface und Test vererben Cloneable, gibt es nur ein einziges Cloneable Basisobjekt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top