2009-09-28 7 views
10

Angenommen, ich habe die folgende (vereinfachte Fall):Copykonstruktor: deep eine abstrakte Klasse Kopieren

class Color; 

class IColor 
{ 
public: 
    virtual Color getValue(const float u, const float v) const = 0; 
}; 

class Color : public IColor 
{ 
public: 
    float r,g,b; 
    Color(float ar, float ag, float ab) : r(ar), g(ag), b(ab) {} 
    Color getValue(const float u, const float v) const 
    { 
     return Color(r, g, b) 
    } 
} 

class Material 
{ 
private: 
    IColor* _color; 
public: 
    Material(); 
    Material(const Material& m); 
} 

Jetzt gibt es eine Möglichkeit für mich eine tiefe Kopie des abstrakten IColor im Copykonstruktor von dem zu tun Material? Das heißt, ich möchte, dass die Werte von m._color (eine Farbe, eine Textur) kopiert werden, nicht nur der Zeiger auf IColor.

Antwort

7

Sie könnten Ihrer Schnittstelle eine clone() -Funktion hinzufügen.

1

Sie müssen diesen Code selbst dem Materialkopierkonstruktor hinzufügen. Dann Code, um den zugewiesenen IColor in Ihrem Destruktor freizugeben.

Sie möchten auch einen virtuellen Destruktor zu IColor hinzufügen.

Die einzige Möglichkeit, eine tiefe Kopie automatisch durchzuführen, wäre, eine Farbe direkt anstelle eines Zeigers auf einem IColor zu speichern.

+0

Warum wird durch das Speichern eines Zeigers auf IColor die Deep Copy deaktiviert? –

+0

Weil es standardmäßig die Zeigeradresse in die kopierte Zeigeradresse kopiert. Es wird nicht kopiert, worauf gezeigt wird, und dann den Zeiger neu einstellen. Luke hat den besten Vorschlag, eine vom Kopierkonstruktor aufgerufene Funktion clone() zu erstellen. –

0

einen Klon() Methode, um Farbe ist wahrscheinlich am besten Hinzufügen, aber wenn Sie diese Option nicht haben, wäre eine andere Lösung sein dynamic_cast verwenden IColor * zu * Farbe zu werfen. Dann können Sie den Color-Copy-Konstruktor aufrufen.

+0

Aber du weißt nicht, ob es eine Farbe oder eine Textur ist, wie kannst du dann dynamic_cast? – Barth

+0

Wenn das Objekt nicht vom Typ Farbe ist, gibt dynamic_cast (_color) null zurück. (Dynamic Cast/RTTI kann den tatsächlichen Typ erkennen, solange die Klasse über mindestens eine virtuelle Methode verfügt). Was Sie also tun können, ist die Möglichkeiten zu testen. Das ist kein Spaß und fast immer schlimmer, als wenn man eine clone() -Methode benutzt, aber es gibt seltene Situationen, in denen man so etwas machen muss. –