Operator overloading - was ist falsch?
-
Hallo,
ich lerne die Basics vom Operator overloading. Soweit verstehe ich dass 3 * string zum Beispiel "a a a" erzeugen kann: http://coliru.stacked-crooked.com/a/97cbaf4638283343
Nun habe ich ein Beispiel mit 3 * MyClass und erhalte aber keine erweiterte Liste sondern einen Fehler... was mache ich falsch:
#include <iostream> #include <vector> using namespace std; class B { public: B(const string & _n) : name(_n) {} friend ostream & operator<<(ostream & out, const B & b); private: string name; }; ostream & operator<<(ostream & out, const B & b) { cout << b.name << endl; return cout; } class C { public: C(const B & b) { data.push_back(b); } void print() const { for (size_t i=0; i < data.size(); i++) { cout << data[i] << endl; } } /* C operator+=(const C & c) { return *this + c; } * */ friend const C operator*(int n, const C & a); private: std::vector<B> data; }; const C operator*(int n, const C & a) { C c(a); for (int m=0; m < n; m++) { c.data.push_back( a.data[m] ); } return c; } int main() { cout << "hello" << endl; C a(3 * B("world")); a.print(); return 0; }
-
- Fehler:
Du postest nicht, was Du für einen Fehler erhältst
Aber so beim schnellen Überfliegen sieht es für mich so aus, als ob Du
3 * ein Objekt vom Typ B
'rechnen' willst.
B kennt aber den Operator '*' gar nicht ...
- Fehler:
-
@patrickm123 sagte in Operator overloading - was ist falsch?:
sondern einen Fehler... was mache ich falsch:
Du verschweigst Details.
-
Ich habe nicht versucht den Code zu verstehen. Nur, was mir sofort ins Auge gestochen ist:
@patrickm123 sagte in Operator overloading - was ist falsch?:
const C operator*(int n, const C & a) {
Was glaubst Du bringt das erste
const
da?@patrickm123 sagte in Operator overloading - was ist falsch?:
ostream & operator<<(ostream & out, const B & b) { cout << b.name << endl; return cout; }
Wofür ist hier der Parameter
out
?@patrickm123 sagte in Operator overloading - was ist falsch?:
Nun habe ich ein Beispiel mit 3 * MyClass und erhalte aber keine erweiterte Liste sondern einen Fehler...
Hast Du denn verstanden was der
operator*()
in Deinem Beispiel@patrickm123 sagte in Operator overloading - was ist falsch?:
const string operator*(int n, const string & s) { string s2; for (int m=0; m < n; m++) { s2 += " " + s; } return s2; }
tut?
-
Dieser Beitrag wurde gelöscht!
-
@Swordfish sagte in Operator overloading - was ist falsch?:
const C operator*(int n, const C & a) {
Mit dem "const" will ich vorbeugen dass eine Expression wie (a*b) = 4 möglich ist, war im Kontext LValues vs RValues wie hier S. 299 beschrieben
Mit
ostream & operator<<(ostream & out, const B & b)
Bezwecke ich dass ich << verketten kann,
cout << a << b << endl;
Ja, der Operator * soll die Funktion operator* aufrufen. Das Ergebenisse in C weggeschrieben werden. Und dann die Ausgabe "Hello world world world"... es kommt aber nur ein Hello World, vermutlich wird das Ergebnis nicht weggeschrieben. Kann später nochmal einen Versuch starten.
-
@patrickm123 sagte in Operator overloading - was ist falsch?:
Mit dem "const" will ich vorbeugen dass eine Expression wie (a*b) = 4 möglich ist, war im Kontext LValues vs RValues wie hier S. 299 beschrieben
Das geht sowieso nicht weil es weder für deine
C
- noch für DeineB
-Hugos einen Konstruktor gibt der einenint
nimmt. (Und wenn es möglich wäre, es wäre sch***-egal. Das zurückgegebene Dingsti ist ein temporary ... kratzt niemanden.)@patrickm123 sagte in Operator overloading - was ist falsch?:
Mit
ostream & operator<<(ostream & out, const B & b)Bezwecke ich dass ich << verketten kann,
Ja. Schön. Und für was ist der Parameter
out
?@patrickm123 sagte in Operator overloading - was ist falsch?:
vermutlich wird das Ergebnis nicht weggeschrieben.
Du hast einen Logikfehler in deiner Multiplikationiererei.
#include <vector> #include <string> #include <iostream> class B { std::string name; public: B(std::string const &name = "") // identifier mit unterstrichen ... lass das. 1) : name{ name } {} friend std::ostream& operator<<(std::ostream &out, B const &b) { return out << b.name; } friend B operator*(int n, B const &b) { B result; auto foo { b.name }; for (int i = 0; i < n; ++i) result.name += (i ? " " : "") + foo; return result; } }; class C { std::vector<B> data; public: C(B const &b) : data{ b } {} void print() const { for (auto const &d : data) std::cout << d << '\n'; } }; int main() { std::cout << "hello\n"; C a{ 3 * B("world") }; a.print(); }
Ich weiß aber nicht warum
C
einenvector<B>
haben soll oder was das ganze werden soll wenn's fertig ist. Operatorüberladungen ausprobieren? Mach's mit Typen wo's Sinn macht ....- [lex.name]/3.2, Ja, es ist nicht global scope, aber trotzdem. Besonders in einem Konstruktor ist es hässlich und bringt genau garnichts.
-
Danke für dein beispiel!
Ja, jetzt habe ich noch eine Variante gefunden, die * mit + .. + .. + .. identisch ist. In der Tat geht es nur um ein Verständnis vom Overloading:#include <iostream> #include <vector> using namespace std; class B { public: B(const string & n) : name(n) {} friend ostream & operator<<(ostream & out, const B & b); private: string name; }; ostream & operator<<(ostream & out, const B & b) { out<< b.name << endl; return out; } class C { public: C() { } C(const B & b) { data.push_back(b); } void print() const { for (size_t i=0; i < data.size(); i++) { cout << data[i] << endl; } } friend const C operator*(int n, const C & a); friend const C operator+(const C & a, const C & b) ; friend const C operator*(int n, const B & b) ; private: std::vector<B> data; }; const C operator*(int n, const C & a) { C c(a); for (int m=1; m < n; m++) { c.data.push_back( a.data[0] ); } return c; } const C operator*(int n, const B & b) { C c; for (int m=0; m < n; m++) { c.data.push_back( b ); } return c; } const C operator+(const C & a, const C & b) { C z(a); for (size_t i=0; i < b.data.size(); i++) { z.data.push_back(b.data[i]); } return z; } int main() { cout << "hello" << endl; C a1( C(B("world")) + C(B("world")) + C(B("world"))); cout << "-----" << endl; a1.print(); cout << "-----" << endl; C a2( 3 * B("world")); a2.print(); return 0; }
Danke für Dein Feedback zum Init-Liste Style, den muss ich beim nächsten Mal umsetzen.