2009-05-19 10 views
0

Hier ist eine Clone() Implementierung für meine Klasse:Implementieren Clone() -Methode in der Basisklasse

MyClass^ Clone(){ 
     return gcnew MyClass(this->member1, this->member2); 
    } 

Jetzt habe ich etwa 10 von MyClass abgeleiteten Klassen. Die Implementierung ist in jedem Fall gleich. Aufgrund der Tatsache, dass ich gcnew mit dem tatsächlichen Klassennamen in jedem Fall aufrufen muss, muss ich 10 nahezu identische Implementierungen von Clone() erstellen.

Gibt es eine Möglichkeit, eine einzige Clone()-Methode in der Basisklasse zu schreiben, die alle 10 abgeleiteten Klassen bedient?

Bearbeiten: Gibt es eine Möglichkeit, den Konstruktor einer Klasse über eines seiner Objekte aufzurufen? In einer Weise, die den tatsächlichen abgeleiteten Klassenkonstruktor aufruft. Etwas wie:

MyClass ^obj2 = obj1->Class->Construct(arg1, arg2); 

Ich tue dies auf C++/CLI aber Antworten aus anderen Sprachen sind willkommen.

Antwort

3

Im einfachen alten C++, können Sie th tun ist mit kompilierbarer Polymorphie (das seltsam wiederkehrende Vorlagenmuster). Angenommen, Ihre abgeleiteten Klassen kopierbar sind, können Sie einfach schreiben:


class Base 
{ 
public: 
    virtual Base* Clone() const = 0; 
//etc. 
}; 
template <typename Derived> 
class BaseHelper: public Base 
{ 
    //other base code here 

    //This is a covariant return type, allowed in standard C++ 
    Derived * Clone() const 
    { 
     return new Derived(static_cast<Derived *>(*this)); 
    } 
}; 

Dann mag es verwenden:


class MyClass: public BaseHelper<MyClass> 
{ 
    //MyClass automatically gets a Clone method with the right signature 
}; 

Beachten Sie, dass Sie nicht wieder von einer Klasse ableiten können und haben es nahtlos arbeiten - Sie haben die Option, die Zwischenklassen neu zu templatieren, zu "entwerfen" oder erneut zu schreiben Clone.

0

Nicht in C++, die ich kenne. Wie Sie sagen, müssen Sie in jeder Implementierung von Clone() ein Objekt einer anderen Klasse erstellen.

0

Hm, ich denke, Sie können Factory-Muster hier verwenden. D.h .:

MyClass Clone(){ 
    return MyClassFactory.createInstance(this.getClass(), this.member1, this.member2, ...); 
} 

In der Fabrik würden Sie Instanz der Unterklasse erstellen haben, basierend auf übergeben Klassentyp. Also wahrscheinlich hat es die gleichen Nachteile wie Ihr Ansatz.

0

Ich würde vorschlagen, Kopierkonstruktoren stattdessen (wie abgeleitete Klassen können auch den Kopierkonstruktor der Basisimplementierung aufrufen) - auch praktisch, wie es Gebiet für C++ - Programmierer bekannt sein wird.

Möglicherweise können Sie eine einzelne Clone-Methode erstellen, die über Reflection den Kopierkonstruktor in dieser Instanz auf sich selbst aufruft.

Möglicherweise auch erwähnenswert, dass Jeffrey Richter in der Framework Design Guidelines Buch sagte: "Die ICloneable Schnittstelle ist ein Beispiel für eine sehr einfache Abstraktion mit einem Vertrag, der nie explizit dokumentiert wurde. Einige Typen implementieren Clone Methode, so dass es Führt eine flache Kopie des Objekts aus, während einige Implementierungen eine tiefe Kopie ausführen Da die Methode Clone dieser Schnittstelle nie vollständig dokumentiert wurde, wissen Sie bei Verwendung eines Objekts mit einem Typ, der ICloneable implementiert, nie, was Sie erhalten werden . Dies macht die Schnittstelle unbrauchbar "(Hervorhebung von mir)