Konstruktoren und Kopiekonstruktoren
-
Als Ergänzung dazu: Der Compiler erzeugt automatisch einen Copy-Konstruktor, operator= und Destruktor* für deine Klassen, wenn du keinen explizit angibst (diese führen in festgelegter Reihenfolge die entsprechenden Methoden für die Basisklasse(n) und alle Member aus). Eine eigene Version davon brauchst du nur, wenn die Default-Version nicht möglich ist (z.B. Zuweisung für Klassen mit konstanten Membern oder Referenzen) oder nicht das macht, was du erwartest (z.B. Zeiger werden per Default flach kopiert).
(und beim Copy-Ctor mußt du das Objekt per Referenz übergeben, weil eine Übergabe per Wert zu einer Endlosrekursion führen würde - um das Argument des Copy-Ctors zu liefern, müsste der übergebene Wert kopiert werden - und dazu wird wieder der Copy-Ctor verwendet)
PS: Übrigens ist die Übergabe als "const Typ&" praktisch eine Wert-Übergabe, weil du das übergebene Objekt nicht ändern darfst - nur sparst du dir auf diese Weise unnötige Kopien (die mitunter recht langsam sind).
* wenn du der Klasse keine eigenen Konstruktoren spendierst, bekommst du auch noch einen automatisch erzeugten Default-Konstruktor.
-
Hm also ich versuche mal zusammen zu fassen:
- Eine klasse ist der Oberbegriff für eine größere Anzahl Objekte mit gleichen Eigenschaften oder Methoden
- Ein Objekt ist ein virtueller "Gegenstand" der gewisse Eigenschaften der Objekte, der Klasse zu der er gehört haben muss (muss er immer alle haben oder kann ich auch objekte erzeugen, denen ich zb nur namen gebe?)
- Der Konstruktor erstellt eine art Standardobjekt
- Mit dem KopyKonstruktor kann ich objekte erstellen, die ihre individuellen Werte über die Parameter bekommen (zb. cellphone h1("Nokia N70", 900, 1250); erstellt handy h1 mit dem namen nmokia N70, rf Power 900 und accucapacity von 1250) und ansonsten andere Eigenschaften des Standard Objekts automatisch kopiert bekommen (wobei sich mir da immer noch die Frage stellt wieso das nicht ohne kopy konstruktor bzw nur mit dem normalen konstruktor geht)
- Mit const &typ übergebe ich einen Wert den ich nicht ändern darf (wobei ich das in dem Zusammenhang nicht verstehe, der Name ist doch immer ein anderer?)
Man möge mich bitte korrigieren denn das ist es wie ich es verstanden habe und das wirkt auf mich wie großer Müll

-
ThaRealMatix schrieb:
Eine klasse ist der Oberbegriff für eine größere Anzahl Objekte mit gleichen Eigenschaften oder Methoden
Abgesehen davon, daß das vorletzte Wort "und" lauten sollte, ist das korrekt
Ein Objekt ist ein virtueller "Gegenstand" der gewisse Eigenschaften der Objekte, der Klasse zu der er gehört haben muss (muss er immer alle haben oder kann ich auch objekte erzeugen, denen ich zb nur namen gebe?)
Das Objekt hat alle Eigenschaften seiner Klasse, kann aber in verschiedenen Ausprägungen vorliegen (z.B. hat jedes Auto eine Höchstgeschwindigkeit, aber der Wert unterscheidet sich zwischen einem Ferrari und einem VW Polo)
Der Konstruktor erstellt eine art Standardobjekt
"Konstruktor" heißen alle Methoden, die auf irgendeine Art ein Objekt der Klasse erzeugen können. Besondere Bedeutung haben der Default-Konstruktor (erzeugt ein Standardobjekt ohne zusätzliche Informationen) und der Kopier-Konstruktor (kopiert die Attributwerte eines existierenden Objekts, um ein neues zu erzeugen).
Mit dem KopyKonstruktor kann ich objekte erstellen, die ihre individuellen Werte über die Parameter bekommen (zb. cellphone h1("Nokia N70", 900, 1250); erstellt handy h1 mit dem namen nmokia N70, rf Power 900 und accucapacity von 1250) und ansonsten andere Eigenschaften des Standard Objekts automatisch kopiert bekommen (wobei sich mir da immer noch die Frage stellt wieso das nicht ohne kopy konstruktor bzw nur mit dem normalen konstruktor geht)
Was du da beschreibst, ist ein beliebiger Konstruktor. Der Kopier-Konstruktor nimmt ein fertiges Objekt und überträgt dessen Eigenschaften komplett auf ein weiteres (z.B.
cellphone h2=h1;(jetzt hast du zwei identische Handys)).Mit const &typ übergebe ich einen Wert den ich nicht ändern darf (wobei ich das in dem Zusammenhang nicht verstehe, der Name ist doch immer ein anderer?)
Mit der Übergabe als Referenz
typ& wertwird der Parameter zu einem neuen Namen des Objekts, das übergeben wurde - das spart Kopier-Operationen (wenn eine Kopie überhaupt möglich ist) und ermöglicht es der Funktion auch, das Objekt direkt zu manipulieren. Mit der Übergabe als Werttyp wertübergibst du eine eigenständige Kopie des Objekts - Änderungen, die in der Funktion stattfinden, machen sich nach außen nicht bemerkbar, aber dafür muß das Objekt kopiert werden*.
Die Übergabe als konstante Referenzconst typ& wertverbindet sozusagen die Vorteile beider Lösungen - durch die Referenz sparst du dir das Kopieren und das 'const' sorgt dafür, daß das übergebene Objekt nicht verändert werden darf.* Es gibt Objekte, bei denen ist es technisch nicht möglich sie zu kopieren (z.B. die IO-Streams) oder sie sind so groß, daß das Kopieren eine halbe Ewigkeit brauchen würde (das betrifft zum Beispiel Containerklassen). Bei solchen Objekten ist eine Übergabe als Wert nicht möglich oder ineffizient. Der Copy-Ctor ist ein anderes Beispiel, wo eine Wert-Übergabe technisch nicht möglich ist.
-
ThaRealMatix schrieb:
Hm also ich versuche mal zusammen zu fassen:
- Eine klasse ist der Oberbegriff für eine größere Anzahl Objekte mit gleichen Eigenschaften oder Methoden
Ich würde eher sagen eine Klasse ist eine Vorlage/Schablone für Objekte. Eine Klasse selbst hat keine Werte, ein Objekt einer klasse schon. Wir Menschen denken auch quasi Objektorientiert. Bei dem Begriff "Haus" haben wir eine Vorstellung was gemeint ist, auch wenn dies noch lange nichts über das konkrete Aussagt (Ein Objekt der Klasse Haus könnte z.b. lauten: 2-Familienwohnung in guter Lage,...)
- Ein Objekt ist ein virtueller "Gegenstand" der gewisse Eigenschaften der Objekte, der Klasse zu der er gehört haben muss (muss er immer alle haben oder kann ich auch objekte erzeugen, denen ich zb nur namen gebe?)
Ein Objekt ist ein konkreter Gegenstand, die Klasse die grobe Umschreibung. Eine Klasse beschreibt was für Merkmale jedes Objekt dieser Klasse hat, ein Objekt hat aber konkrete Eigenschaftswerte (Die Klasse sagt es gibt eine Eigenschaft Farbe, das konkrete Objekt sagt: Farbe=gelb...).
Dein Satz hier ist auch sehr missverständlich. Von einer Klasse kann man mehrere Objekte anlegen, jedes Objekt hat alle Eigenschaften der Klasse, aber in eigenen konkreten Ausprägungen. Sie können identische Werte haben, müssen aber nicht.
Eine Klasse braucht auch keinen Speicherplatz, da sie selbst nicht "existiert" ein Objekt belegt Speicherplatz weil es im gegensatz zur Klasse eine Existenz hat (greifbar ist).
ThaRealMatix schrieb:
- Der Konstruktor erstellt eine art Standardobjekt
Du kannst mehrere Konstruktoren haben, jeder Konstruktor dient dazu ein Objekt der Klasse mit bestimmten Vorbelegungen anzulegen. Von einem Standardkonstruktor spricht man wenn dieser keine Angaben braucht (Dies kann auch einer mit Parametern sein, sofern diese alle Vorgabewerte besitzen).
class Klasse {...}; int main() { Klasse objekt1; // objekt1 angelegt mittels Standardkonstruktor Klasse objekt2(1); // objekt2 angelegt über einen Konstruktor mit einem Zahlenwert Klasse objekt3(objekt2); // objekt3 angelegt als Kopie von objekt2 über Kopierkonstruktor }ThaRealMatix schrieb:
- Mit dem KopyKonstruktor kann ich objekte erstellen, die ihre individuellen Werte über die Parameter bekommen (zb. cellphone h1("Nokia N70", 900, 1250); erstellt handy h1 mit dem namen nmokia N70, rf Power 900 und accucapacity von 1250) und ansonsten andere Eigenschaften des Standard Objekts automatisch kopiert bekommen (wobei sich mir da immer noch die Frage stellt wieso das nicht ohne kopy konstruktor bzw nur mit dem normalen konstruktor geht)
Nein, ein Kopierkonstruktor kopiert alle Werte eines bestehenden Objektes und legt damit ein neues an:
cellphone h1("Nokia N70", 900, 1250);
cellphone h2(h1);Im ersten Fall wird ein Konstruktor im zweiten der Kopierkonstruktor aufgerufen. h2 ist eine Kopie, also auch ein Nokia N70 mit den gleichen Eigenschaften.
ThaRealMatix schrieb:
- Mit const &typ übergebe ich einen Wert den ich nicht ändern darf (wobei ich das in dem Zusammenhang nicht verstehe, der Name ist doch immer ein anderer?)
Das übergebene Objekt darf nicht geändert werden. Du willst doch den Inhalt kopieren und nicht ändern. Du kannst ja auch von einem konstanten Objekt eine Kopie anlegen, und das "const" zeigt das hier keine Änderung an dem Übergebenen gemacht wird.
ThaRealMatix schrieb:
Man möge mich bitte korrigieren denn das ist es wie ich es verstanden habe und das wirkt auf mich wie großer Müll

Ich hoffe damit wird dir etwas weitergeholfen.
cu André
-
Hm... okay also ein Konstruktor erschafft immer ein Objekt. ich kann objekte über einen Konstruktor mit Parametern erschaffen, z.b
cellphone(const string & aName , int rfPower, int accuCapacity);
(Ich nehme mal an, dass ich in dem konstruktor dann aber angeben muss, welcher Parameter welcher Objekteigenschaft zuzuordnen ist, also mit
{
name =h.name;
rfPower = h.rfPower;
accuCapacity = h.accuCapacity;
accuCharge = h.accuCharge;
cellphoneOperationStatus = h.cellphoneOperationStatus;
startTime = h.startTime;
}?)
Ein kopiekonstruktor macht eine einfache Kopie eines bestehenden Objektes. Aber wozu ist dann der hier?
cellphone::cellphone(const cellphone& h): accuVoltage(h.accuVoltage)
{
name =h.name;
rfPower = h.rfPower;
accuCapacity = h.accuCapacity;
accuCharge = h.accuCharge;
cellphoneOperationStatus = h.cellphoneOperationStatus;
startTime = h.startTime;
}Er kann doch gar keine kopie erstellen, weil es noch kein zu kopierendes Objekt gibt? Ausserdem müsste ich doch als "Parameter" das zu kopierende Objekt angeben?
Ich bin total verwirrt

-
ThaRealMatix schrieb:
Hm... okay also ein Konstruktor erschafft immer ein Objekt. ich kann objekte über einen Konstruktor mit Parametern erschaffen, z.b
cellphone(const string & aName , int rfPower, int accuCapacity);
(Ich nehme mal an, dass ich in dem konstruktor dann aber angeben muss, welcher Parameter welcher Objekteigenschaft zuzuordnen ist, also mit
Ja - aber dabei muß nicht jedes Objektattribut direkt aus den Parametern hervorgehen. (bei deinem Paramter-Ctor oben werden z.B. accuCharge mit 0 und cellphoneOperationStatus mit bereit vorbelegt)
Ein kopiekonstruktor macht eine einfache Kopie eines bestehenden Objektes. Aber wozu ist dann der hier?
cellphone::cellphone(const cellphone& h): accuVoltage(h.accuVoltage) { name =h.name; rfPower = h.rfPower; accuCapacity = h.accuCapacity; accuCharge = h.accuCharge; cellphoneOperationStatus = h.cellphoneOperationStatus; startTime = h.startTime; }Die Kopie wird letztlich erzeugt, indem jeder Teil des übergebenen Objekts (hier als 'h' bezeichnet) kopiert wird. Und genau das macht dieser Copy-Ctor.
Er kann doch gar keine kopie erstellen, weil es noch kein zu kopierendes Objekt gibt? Ausserdem müsste ich doch als "Parameter" das zu kopierende Objekt angeben?
Du übergibst als Parameter doch ein existierendes Objekt namens
const cellphone& h- und genau von diesem Objekt wird eine Kopie angelegt.
-
ehm... gut.... aber wann wurde denn das Objekt h erzeugt? Mit dem Parameter Konstruktor? Der wurde in der main ja nie aufegrufen?
-
Vermutlich ja - in deinem Beispielprogramm wird der Copy-Ctor übrigens gar nicht verwendet (außer evt. für Parameterübergaben per Wert). Ich nehme mal das Beispielfragment von asc:
cellphone h1("Nokia N70", 900, 1250); cellphone h2(h1);Das Objekt h1 wurde mit dem "normalen" Ctor erzeugt, h2 mit dem Copy-Ctor (wobei h1 als Parameter 'h' übergeben wurde).
-
ehm moment... jetzt bin ich verwirrt...
Also in dem Programm wird der
cellphone::cellphone(const cellphone& h): accuVoltage(h.accuVoltage) { name =h.name; rfPower = h.rfPower; accuCapacity = h.accuCapacity; accuCharge = h.accuCharge; cellphoneOperationStatus = h.cellphoneOperationStatus; startTime = h.startTime; }konstruktor demnach gar nicht benutzt?
-
Probier's doch aus, indem du eine Ausgabe dort reinsetzt

In dem Code, den du gepostet hast, braucht es keinen Copy-Ctor. Die einzige Stelle, bei der ich mir nicht sicher bin, wäre die charger::chargeAccu()-Methode (es wäre also durchaus möglich, daß deren Parameter per Wert übergeben und dafür der Copy-Ctor verwendet wird).