Wie Klone ich eine Klasse

gedon

Lieutenant
Registriert
Apr. 2008
Beiträge
614
Hallo,

ich komme momentan nicht weiter und auch google half mir bis jetzt nicht wirklich.
Ich mache das nur als Hobby, also falls ich mich etwas unbeholfen anstelle, wisst ihr wieso ;)
deswegen benutze ich auch das .net.

Ich habe eine Klasse mit verschiedenen Variablen, darunter auch mehrere ArrayList. Das stellt dann immer einen kompletten Datensatz dar, der kommt dann wiederum in eine weitere ArrayList (main_AL).
Also so:

Code:
ArrayList^ main_AL = gcnew ArrayList();

...

for( ... )
{
myClass^ mc = gcnew myClass();
mc->Var1 = ...
mc->Var2 = ...
mc->AL1 = ...
main_AL->Add( mc->Clone() );
}



// hier noch die Funktion zum Clonen
public: System::Object^ Clone()
{	
myClass^ newmc = (myClass^) this->MemberwiseClone();
return newmc;
}

Das Problem ist jetzt, dass alle Variablen aus der Klasse geclont werden, also komplett inkl. der Werte, nur die ArrayList innerhalb der Klasse wollen nichts davon wissen und es werden immer nur Referenzen erstellt.
Soweit ich das jetzt verstanden habe, liegt es daran, dass die ArrayList als statische Member erzeugt wurden und deshalb MemberwiseClone nur Referenzen erzeugt.

Wie bekomme ich das nun hin?
Gibt es Alternativen?
 
Naja, man muss sich halt Gedanken machen, wie man vernünftig klont. Es gibt hier keine generelle richtige oder falsche Variante...

Der Einfachheit halber wird beim Klonen eben oft nur die Adresse geklont (also eine Referenz erstellt). Das hat Leistungsgründe... was spricht dagegen, in Clone über die ArrayList zu iterieren und jedes enthaltene Element zu klonen?

(Zu dem Thema gibts große Diskussionen im Übrigen...)

Edit:
Siehe auch hier:
http://www.dpunkt.de/java/Die_Sprache_Java/Objektorientierte_Programmierung_mit_Java/45.html

ArrayList wird flach geklont ohne eigenes Zutun.
 
1668mib schrieb:
was spricht dagegen, in Clone über die ArrayList zu iterieren und jedes enthaltene Element zu klonen?
Ich finde auch nur solche Aussagen bei google, aber keine richtigen Beispiele. Deshalb tu ich mich auch so schwer.

Wo fände dann die Iteration statt?

Edit: gibt's das auch in c++
 
Zuletzt bearbeitet:
z.B. in etwa so
Code:
public: System::Object^ Clone()
{	
  myClass^ newmc = (myClass^) this->MemberwiseClone();
  
  // deep copy of myArrayList
  newmc->myArrayList = gcnew ArrayList();
  for each (Object o in this->myArrayList) {
    newmc->myArrayList->add(o.clone());
  }
  return newmc;
}

myArrayList durch AL1 usw ersetzen... würde sich evtl auch anbieten dafür eine Hilfsmethode zu schreiben...
Code:
protected static ArrayList^ deepCopy(ArrayList^ list)  // keine Ahnung wie die Syntax hier sein muss, ich nutz kein C++/CLI, weil wenn schon .net dann gleich C#...
{
  ArrayList^ result = gcnew ArrayList();
  for each (Object o in list) {
    result->add(o.clone());
  }
  return result;
}

public: System::Object^ Clone()
{	
  myClass^ newmc = (myClass^) this->MemberwiseClone();
  
  // deep copy of myArrayList
  newmc->myArrayList = deepCopy(this->myArrayList);
  return newmc;
}

Offtopic: Statt ArrayList solltest du übrigens evtl lieber einen generischen Typ nehmen, also z.B.
List<MeineKlasse>

Edit:
Verwechsel C++ nicht mit C++/CLI...

Edit:
MemberwiseClone stellt allgemein nur ne flache Kopie her... der Link sollte nur das Problem verdeutlichen...
 
Zuletzt bearbeitet:
Das hilft auch nicht weiter.
Im ersten Bsp. ist es die Zeile

newmc->myArrayList = gcnew ArrayList();

die die original ArrayList überschreibt und beim 2. ist es diese

newmc->myArrayList = deepCopy(this->myArrayList);
 
Wieso überhaupt clonen ? Du erstellst doch in der For-Schleife jedesmal eine neue Instanz von myClass ..
 
Wenn es so einfach wäre...
Das Programm nimmt aber immer den selben Speicherbereich für die ArrayList.

Edit: OK, habe es hinbekommen. Wieder was gelehrnt. Man kann eine AL doch ohne static erstellen, jetzt klappt es auch ohne zusätzlichen Code
Ergänzung ()

1668mib schrieb:
Offtopic: Statt ArrayList solltest du übrigens evtl lieber einen generischen Typ nehmen, also z.B.
List<MeineKlasse>

Um darauf noch einmal zurückzukommen, wo ist denn der Vorteil, wenn ich anstatt der main_AL eine List nehme?
 
Zuletzt bearbeitet:
Zurück
Oben