cout.operator ...
-
Ich wollte es nur noch mal etwas ausführlicher aufschreiben
-
Was mir grad zu dem Thema einfällt. Ich hab vor längerer Zeit mal so halbherzig ne Stringklasse angefangen. Dort habe ich IIRC den char*-operator überladen, so dass er nen zeiger auf den intern gespeicherten char zurückgibt. das hat auhc geklappt, aber cout << Mystring; hat mir immer die adresse des internen strings zurückgegeben, wohingegen cout <<(char*)Mystring; funktioniert hat. Falls da grad jemand ne kurze Erklärung hat, könnte er sie ja posten ...
-
Hallo,
der Grund steht für den Template-Kenner mit zusätzlichen VC-Kentnissen etwas versteckt bereits in meinem oberen BeitragDie freie Funktion operator<< die einen const char* ausgeben kann ist eine *Template*-Funktion und sieht beim VC so aus:
template<class _E, class _Tr> inline basic_ostream<_E, _Tr>& operator<<(basic_ostream<_E, _Tr>& _O, const _E *_X)
Bei einem:
cout << "Hallo";
wird _E zu char und _Tr zu char_traits<char>. Der Parameter _X ist also vom Typ
const char*.Bei der Herleitung von Templateparameter finden aber grundsätzlich keine Benutzerdefinierte Konvertierungen statt.
Der Aufruf:DeineStringKlasse s; cout << s;
kann nicht zum Aufruf des entsprechenden Operators führen, da s nicht vom Typ const char* ist und der Konvertierungsoperator nicht berücksichtigt wird.
Die Memberfunktion operator << die ein void*-erwartet ist kein Template sondern eine normale Funktion. Hier werden selbstverständlich alle erlaubten Konvertierungen durchgeführt.
DeineStringKlasse s; cout << s;
Hier wird also erst s nach char* mittels einer Benutzer-definierten Koonvertierung gewandelt und dann char* nach void* durch eine Standardkonvertierung.
Bis hierhin ist der VC im Recht. Allerdings schreibt der Standard zusätzlich zu der oben genannten freien Funktion noch eine Funktion:
[code type="c++"] template<class _E, class _Tr> inline basic_ostream<_E, _Tr>& operator<<(basic_ostream<_E, _Tr>& _O, const char* )
vor. Da hier der zweite Parameter nicht von einem Templateparameter abhängt, werden für diesen auch benutzerdefinierte Konvertierungen durchgeführt.
DeineStringKlasse s; cout << s;
würde also diese Funktion aufrufen.
Der VC versäumt allerdings die Bereitstellung einer solchen Funktion.
-
Was muss man denn nun machen, damit cout.operator << ("Hallo Welt") beim MSVC++ den String "Hallo Welt" ausgibt?
-
operator<<(cout,"Hello World");
aufrufen?
-
Man löst dieses Problem dann, indem man auch den <<-operator überlädt?
-
int main() { string s = "Hallo3"; cout << "Hallo" << endl; cout.operator <<(L"Hallo1") << endl; cout.operator <<(L"Hallo2") << endl; cout.operator <<(s.c_str()) << endl; operator <<(cout,"Hallo4"); cin.get(); return 0; }
-
Man löst dieses Problem dann, indem man auch den <<-operator überlädt?
Falls du noch dein Stringproblem meinst.
Meine Lösung wäre:
1. Man entfernt umgehend die implizite Konvertierung und ersetzt sie durch eine explizite Methode (à la c_str). Implizite Konvertierungen bringen häufig Probleme mit sich und es lohnt sich in dieser Situation einfach nicht diese in Kauf zu nehmen. Außerdem orientiere ich mich gerne an Designs, die sich bereits etabliert haben (std::string verzichtet z.B. auf eine implizite Konvertierung nach char*. Die MFC-Klasse CString hat eine solche, die Klassenbibliothek gilt aber nirgends auch nur halbwegs als Beispiel für gutes Design).2. Zusammen mit der Klasse liefert man auch einen operator<< der ein Objekt der Klasse ausgibt.
Fertig. Weniger Mehrdeutigkeiten, weniger Überaschungen.
-
Original erstellt von HumeSikkins:
**Die MFC-Klasse CString hat eine solche, die Klassenbibliothek gilt aber nirgends auch nur halbwegs als Beispiel für gutes Design).
**Doch
Bei Marcus als Beispiel fürs Refcounting
Naja, was kann es bei impliziten KOnvertierungen noch für Probleme geben? CString hat aber dazu ja auch noch ne Funktion analog zu c_str: GetBuffer.
[ Dieser Beitrag wurde am 25.06.2003 um 22:05 Uhr von dEUs editiert. ]
-
Ich empfinde C++ an dieser Stelle als unbefriedigend und übermäßig kompliziert. Manche denken sogar, "<<" und "operator <<" seien das Gleiche. Offenbar gibt es hier zusätzlich Ungereimtheiten von Compiler zu Compiler.
-
siehe auch folgenden Wirrwarr: http://www.microsoft.com/msj/archive/SD71.aspx
-
Ich empfinde C++ an dieser Stelle als unbefriedigend und übermäßig kompliziert.
Aha. Ich nicht. Was heißt das jetzt? Und wichtiger. Wie würdest du es besser machen. Natürlich unter den Bedingungen die für C++ gelten (z.B. maximale C-kompatibilität).
Manche denken sogar, "<<" und "operator <<" seien das Gleiche
Manche denken sogar, void main wäre Standard.
Manchmal hilft *lernen* viel mehr als denken. C++ erfordert in vielen Bereichen schlicht und einfach wissen. Intuition allein kommt man in dieser Sprache nicht weit.siehe auch folgenden Wirrwarr
Wieso wirrwarr? Dieses Thema wird in jedem *guten* Anfängerbuch erwähnt und erklärt. Immer auch mit der entsprechenden Lösung.
Natürlich ist C++ komplex (aber das ist eigentlich jede mir bekannte Sprache general-purpose-Sprache).
Auch besonders im Bereich der Auflösung von Funktionsaufrufen.
Deshalb lernt man C++ auch nicht in 21 Tagen oder am Wochenende. Zumindest wenn man mehr als nur "Hello World" will.