'<<' operator überladen
-
Schau Dir nochmal genau an, was Du hier treibst:
CFeld::CFeld(char* string) { for(int i = 0; string[i] != '\0'; i++); dim = i; startptr = new char[dim]; strcpy(startptr, string); }
-
Tachyon schrieb:
Also als Friend deklarieren und dann global überladen.
warum als friend?
-
hab folgende Programme geschrieben#include <string> class mann { public: mann(std::string name) : Name(name) { } friend std::ostream &operator<<(std::ostream &ostr, mann &m); private: std::string Name; }; #include "mann.h" #include <iostream> std::ostream &operator<<(std::ostream &ostr, mann &m) { return ostr << m.Name; } #include "mann.h" #include <iostream> int main() { mann m("Meier"); std::cout << m << std::endl; }Das hab ich dann auch kompiliert und läuft. Aber folgendes Programm läuft nicht da bekomm ich fehlermeldungen:
make g++ -g -c zeit.cc -o zeit.o In file included from zeit.cc:1:0: zeit.h:82:79: error: non-member function ‘std::ostream& std::operator<<(std::ostream&, const std::zeit&)’ cannot have cv-qualifier zeit.cc:203:71: error: non-member function ‘std::ostream& operator<<(std::ostream&, const std::zeit&)’ cannot have cv-qualifier make: *** [zeit.o] Fehler 1// Sicherstellen daß zeit.h nur einmal benutzt wird #ifndef ZEIT_H #define ZEIT_H #include <fstream> namespace std{ class zeit { protected: long int zeitpunkt; public: // ctor zeit(); // allg. ctor mit default-Werten zeit(int sommerzeit, int tag, int monat, int jahr, int stunde, int minuten); // Copy ctor zeit( const zeit& _zeitpunkt ); // dtor virtual ~zeit() {}; // Ohne Funktionalität, für abgeleitete Klassen // Funktion zum setzen der Messzeit mit Vorgabewerten virtual bool setZeitpunkt(int sz = 0, int t = 1, int m = 0, int j = 0, int s = 0, int min = 0); virtual bool setZeitpunkt(long int _z) {zeitpunkt = _z;}; // Zum setzen des Zeitpunkts auf Systemzeit des Rechners virtual bool setHeute(); // Funktion um den Tag zu ändern virtual bool setTag(int _day); // Monatsänderung virtual bool setMonat(int _month); // Jahresänderung virtual bool setJahr(int _year); // Stundenänderung virtual bool setStunde(int _hour); // Minutenänderung virtual bool setMinute(int _minute); // Gibt den Wert des Zeitpunkts zurück als zahl virtual long int getZeitpunkt() const; // Gibt den Tag als Zahl zurück virtual int getTag() const; // Gibt den Monat als Zahl zurück virtual int getMonat() const; // Gibt das Jahr als Zahl zurück virtual int getJahr() const; // Gibt die Stunde als Zahl zurück virtual int getStunde() const; // Gibt die Minute als Zahl zurück virtual int getMinute() const; // Bildschirmausgabe der Zeit in Form: tt.mm.jjjj ss:mm virtual std::ostream& ausgabe(std::ostream& stream) const; // freund da ostream nicht direkt zugreifbar... friend std::ostream& operator<<(std::ostream& output, const std::zeit& wann) const; }; } //-------------------------------------------------------------------- // friend operator zur ausgabe.... //-------------------------------------------------------------------- std::ostream& operator<<(std::ostream& output, const std::zeit& wann) const { std::ostringstream ss; ss << std::setw(2) << std::setfill('0') << wann.getTag(); return(output << ss); }kann mir jemand sagen was ich falsch mache? Bin schon über eine Woche am suchen und finde den Fehler nicht?
/edit pumuckl: code-Tags bitte nochmal üben

-
Die Fehlermeldungen sind doch relativ eindeutig:
zeit.h:82:79: error: non-member function ‘std::ostream& std::operator<<(std::ostream&, const std::zeit&)’ cannot have cv-qualifier
zeit.cc:203:71: error: non-member function ‘std::ostream& operator<<(std::ostream&, const std::zeit&)’ cannot have cv-qualifierMit cv-qualifier ist das "const" in am Ende der Zeilen 55 und 61 deines Codes gemeint.
Der operator<< ist keine Memberfunktion, sondern nur ein friend der Klasse, weswegen du ihn nicht als "const" deklarieren kannst.
-
danke sehr, aber jetzt bin ich nicht wirklich weiter, die referenz sollte doch eigentlich die operatorfunktion sein???
[make
g++ -g -c hauptfenster.cc -o hauptfenster.o
g++ neulesen.o hauptfenster.o zeit.o zucker.o texfunctions.o -o programm
hauptfenster.o: In functionmain': /home/karlscheidt/Dokumente/programmieren/programme\_ks/versuche/zucker20062011/hauptfenster.cc:15: undefined reference tostd::operator<<(std::basic_ostream<char, std::char_traits<char> >&, std::zeit const&)'
collect2: ld returned 1 exit status
make: *** [programm] Fehler 1
]
-
nimm erstmal deine zeit-Klasse aus dem namespace std - der ist reserviert, da darf nicht jeder dran.
Danach schau mal in die FAQ, da gibts einen Eintrag zum Thema "undefined reference"
-
Vielen dank pumuckl,
hab namespace std aus dem Programm genommen und jetzt funktionierts wenn ich auch noch nicht blicke warum, aber warscheinlich find ich diese Lösung bei Stroustrup...
aber eine andere Frage, was meintest du mit sourcecode richtig einbinden? Da steh ich auf der Leitung?
lg
KS
-
thepower schrieb:
hab namespace std aus dem Programm genommen und jetzt funktionierts wenn ich auch noch nicht blicke warum,
Der namespace std ist reserviert, d.h du darfst nichts neues dort einführen. Punkt. Einzige Ausnahme sind Spezialisierungen für Templates aus namespace std, z.B. std::swap.
Der Linkerfehler kam aber vermutlich eher daher, dass du operator<< zwar innerhalb der Klasse zeit im namensraum std als friend deklariert hast, aber ihn nicht im namensraum std definiert hast (sondern im globalen namensraum). ggf. wäre da die freind-deklaration so anzupassen gewesen, dass du den voll qualifizierten Namen (also ::operator<<) angeben müsstest.
Aber wie gesagt, Finger weg von namespace std.
-
pumuckl schrieb:
Einzige Ausnahme sind Spezialisierungen für Templates aus namespace std
Ist das so? Ich dachte bisher, man darf nicht mal das.
-
314159265358979 schrieb:
pumuckl schrieb:
Einzige Ausnahme sind Spezialisierungen für Templates aus namespace std
Ist das so? Ich dachte bisher, man darf nicht mal das.
Ja. Siehe dazu N3242 -> 17.6.4.2
-
314159265358979 schrieb:
pumuckl schrieb:
Einzige Ausnahme sind Spezialisierungen für Templates aus namespace std
Ist das so? Ich dachte bisher, man darf nicht mal das.
Das war schon immer so, sofern selbstdefinierte oder von diesen abgeleitete Typen im Spiel sind.