Fragen zu Konstruktoren
-
Hallo!
Ich spiele gerade etwas damit rum, um zu lernen und zu verstehen ...
Nur verstehen tu ich das leider nicht so ganz.#include <iostream> #include <string> using namespace std; class Klasse { public: Klasse() : Wert("") { cout << "Standardkonstruktor\n"; } Klasse(const Klasse& tmpcl) : Wert(tmpcl.GetWert()) { cout << "Kopierkonstruktor\n"; } Klasse(const string& neu) : Wert(neu) { cout << "Typumwandlungskonstruktor\n"; } const string& GetWert() const; void SetWert(const string&); private: string Wert; }; int main() { Klasse MyString; MyString.SetWert("Hallo!"); cout << "MyString: " << MyString.GetWert() << endl; cin.get(); Klasse MyString2 = MyString; cout << "MyString2: " << MyString2.GetWert() << "\tMyString: " << MyString.GetWert() << endl; cin.get(); MyString2.SetWert("bla"); cout << "MyString2: " << MyString2.GetWert() << "\tMyString: " << MyString.GetWert() << endl; cin.get(); MyString = MyString2; cout << "MyString2: " << MyString2.GetWert() << "\tMyString: " << MyString.GetWert() << endl; cin.get(); MyString = string("neu"); cout << "MyString2: " << MyString2.GetWert() << "\tMyString: " << MyString.GetWert() << endl; cin.get(); return 0; } const string& Klasse::GetWert() const { return Wert; } void Klasse::SetWert(const string& newWert) { Wert = newWert; }Der Code funktioniert so.
Soweit so gut. Nur verstehe ich folgende Dinge nicht:1. Wie oder mit welchem Konstruktor ist es moeglich das
MyString.GetWert();in Zeile 22 wegzulassen, um einfach nurMyStringzu schreiben (sodass der Wert 'Wert' einfach zurueckgegeben wird ohne die MethodeGetWert()).2. Warum ergibt
MyString = "neu"in Zeile 33 einen Compilerfehler? Warum muss hier unbedingtMyString = string("neu")oderMyString = Klasse("neu")stehen? Sollte die Zeichenfolge nicht automatisch zum String konvertiert werden? Ich hab doch gar keinexplicitangegeben ...3. Warum wird der Kopierkonstruktor nur bei
Klasse MyString2 = MyString;ausgefuehrt. Sollte er nicht auch z.b. beiMyString = MyString2;ausgefuehrt werden?Weitere Fragen folgen .... ich versteh so manches nich ... leider

Gruss
Cartman
-
1. Gar nicht. Man könnte da etwas mit dem () basteln, macht imo aber nicht viel Sinn.
2. Das ist keine Initialisierung, sondern eine Zuweisung. Das ist ein essentieller Unterschied. (siehe =-Operator).
3. Dasselbe Problem, wie bei 2. Es wird der =-Operator (Zuweisungsoperator) aufgerufen, nicht der Konstruktor. (Ist ja bereits Initialisiert).
EDIT:
Schreibfehler korrigiert.
Achja..Schau dir mal "die grossen 3" an:
http://www.google.ch/search?q=die+grossen+3+c%2B%2B&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla
official&client=firefox-aDann sollte dir einiges klarer werden.
-
drakon schrieb:
1. Gar nicht. Man könnte da etwas mit dem () basteln, macht imo aber nicht viel Sinn.
Das stimmt so nicht. Für diesen Zweck gibt es Konvertierungsoperatoren.
Klasse::operator const std::string& () const { return Wert; } // ... std::cout << MyString << std::endl; // implizite Konvertierung nach std::stringEdit:
constbei Operator
-
Ich versuch mal kurz zu antworten:
1.) Durch keinen Konstruktor. Was du machen müsstest, ist einen Cast-Operator zu schreiben.
2.) Compiler-Fehler, da du keinen Assignment-Operator von Klasse für std::string oder const char* implementiert hast.
3.) Nein, weil MyString = MyString2 eine Zuweisung ist (wo beide Objekte vorher existieren), während bei Klasse MyString2 = MyString MyString2 erst erzeugt wird. Ist gleichbedeutend mit Klasse MyString2(MyString).
HTH
Edit: zu 1.) Es gibt noch zusätzlich die Möglichkeit, die ostream-operatoren zu überladen für deine Klasse
std::ostream& operator<<(std::ostream&, const Klasse&)
-
Nexus schrieb:
drakon schrieb:
1. Gar nicht. Man könnte da etwas mit dem () basteln, macht imo aber nicht viel Sinn.
Das stimmt so nicht. Für diesen Zweck gibt es Konvertierungsoperatoren.
Stimmt. Ich habe das Beispiel nur schnell überflogen und hatte im Kopf, dass er einen Rückgabewert von Konstruktor haben will. Er hat ja noch nach Konstruktor gefragt.

-
Nexus schrieb:
drakon schrieb:
1. Gar nicht. Man könnte da etwas mit dem () basteln, macht imo aber nicht viel Sinn.
Das stimmt so nicht. Für diesen Zweck gibt es Konvertierungsoperatoren.
Klasse::operator const std::string& () const { return Wert; } // ... std::cout << MyString << std::endl; // implizite Konvertierung nach std::stringEdit:
constbei OperatorMuss man da noch irgendwas im Klassenkopf deklarieren? Weil so funktioniert das nicht

Den Rest habe ich verstanden denk ich

Danke fuer eure Antworten!
Gruss
Cartman
-
Jap. Deklaration gehört in die Klasse.
-
Eric Cartman schrieb:
Muss man da noch irgendwas im Klassenkopf deklarieren? Weil so funktioniert das nicht

Ja, der Cast-Operator ist eigentlich eine normale Memberfunktion. Also muss eine Deklaration mit gleicher Signatur in der Klassendefinition erfolgen.
Mit Konvertierungsoperatoren solltest du allerdings vorsichtig sein: Die Klasse kann so nämlich als String betrachtet werden. Vielleicht gibt es Situationen, wo die implizite Konvertierung nicht erwünscht ist oder sogar zu Konflikten führt; in diesen Fällen ist eine herkömmliche Get-Methode besser geeignet.