Rückgabe von Objekt
-
Folgendes Programm läßt sich nicht übersetzen
Folgende Fehlermeldung:
In functionFoo operator+(const Foo&, const Foo&)': no matching function for call to
Foo::Foo(Foo)'
Foo::Foo(std::string)#include <iostream> #include <string> using namespace std; class Foo { public: Foo() { value = "0"; } Foo(string str) { value = str; } Foo(Foo &source) { value = source.value; } friend Foo operator+(const Foo &left, const Foo &right); friend ostream &operator<<(ostream &out, const Foo &Foo); private: string value; }; Foo operator+(const Foo &left, const Foo &right) { string reverse = "3434"; return Foo(reverse); } ostream &operator<<(ostream &out, const Foo &Foo) { out<<Foo.value; return out; } int main() { Foo x,y,z; z = x+y; cout<<z<<endl; system("pause"); }
wo liegt der Fehler? durch zufall bin ich drauf gekommen den CopyCtor wie folgt abzuändern: Foo(const Foo &source)
irgendwie verstehe ich aber jetzt auch noch nicht warum hier ein const hin muss... das Objekt das ich zurückgebe ist doch nicht const - oder? (anscheinend schon...), aber dann könnte ich das zurückgebene objekt ja nicht mehr verändern... mmmh?
-
am tollsten ist ja, das mein ms compiler obiges programm ohne die änderung am copy ctor ohne probleme übersetzt
-
wo liegt der Fehler?
Du versuchst ein rvalue (nämlich dein temporäres Objekt das bei der Addition aus x und y entsteht) an eine Referenz zu binden (nämlich an den Parameter deines Copy-Ctors der für die by-value-Rückgabe aufgerufen wird) und das ist nicht möglich.
am tollsten ist ja, das mein ms compiler obiges programm ohne die änderung am copy ctor ohne probleme übersetzt
Die Regel, dass temporäre Objekte nur an Referenzen-auf-const gebunden werden dürfen, ist eine, die erst relativ spät zum Standard hinzugefügt wurde. Ältere Compiler erlauben auch die Bindung an normale Referenzen, was aber schnell zu bösen Fehlern führen kann:
// kein Standard-C++, aber manche Compiler erlauben es Foo& ups(Foo& f) { return f; } int main() { Foo& f = ups(Foo("Hallo")); // hier ist f bereits eine "dangling reference" - Ups! }
-
der Kopierkonstruktor gibt erstma garnix zurück.
Der is halt einfach in C++ so definiert
"<classname>(const <classname> &<name>)";
-
Pellaeon schrieb:
Der is halt einfach in C++ so definiert
"<classname>(const <classname> &<name>)";Käse. Siehe 12.8/2
Das:Foo::Foo(const Foo&);
ist genauso ein Copy-Ctor wie z.B.
Foo::Foo(volatile Foo&, int i = 1, const char* c = "Hallo");
-
soweit ich das sehe, ist die ursache des fehlers, daß du die elementfunktion Foo::Foo(Foo) nicht implementiert hast. und wenn du jetzt meinst, das sei nicht nötig, da du sie eh nicht aufrufts, dann irrst du dich! sie wird nämlich implizit in
Foo operator+(const Foo &left, const Foo &right) { string reverse = "3434"; return Foo(reverse); }
bei return aufgerufen! implementiere die Foo::Foo(Foo &source)-funktion und es sollte gehen. oder laß sie auch in der klassen-deklaration weg. dann nimmt der compiler einfach den default-copy-konstruktor (mir fällt jetzt echt nicht mehr ein, wie das verdammte dingens richtig heißt
).
EDIT
stimmt. was ich geschrieben habe ist käse
-
Alternativ hörst du einfach auf das was ich schon geschrieben habe, denn das hat den Vorteil, dass es in diesem Fall einfach mal korrekt ist.
Naja, aber wildes Mutmaßen ist natürlich auch toll...