Unterschiede zu C++ für Umsteiger von Java
-
Simon2 schrieb:
ManOMan schrieb:
...Versuch doch mal in C++ von einer unbekannten Klasse z.B. eine XML Darstellung oder sowas zu erzeugen. ...
Und wogegen oder wofür soll das ein Argument sein ?
Das soll dir zeigen, dass man Reflection nicht mit irgendeiner Lib in C++ nachbauen kann.
Artchi schrieb:
std::string die UTF-8-Unfähigkeit anzulasten, ist falsch. Weil std::string ein ASCII-String ist, und ich für Internationalisierung std::wstring benutzen kann.
Wenn ich Strings über das Internet schicken will, oder als XML-Value schreiben will, muß ich nur in dem Moment eine wstring to UTF-8-Konvertierung nutzen. Und die gibt es zu Hauf im Netz runter zu laden: ICU (IBM) und xstring (Adobe) bieten opensource-Libs für Konvertierungen an.Ja genau das ist es was mich unter anderem an der STL stört, es gibt nicht einen string für alles wie in Java, sondern um z.B. UTF-8 verwenden zu können, brauch ich schon wieder einen anderen
Ich hab dann auch mit wstrings hinundher konvertiert. Was du mit "zur Laufzeit" willst ist mir schleierhaft, wenn ein Programm einen string in utf-8 habenm will, dann muss ich halt konvertieren.
-
Was du mit "zur Laufzeit" willst ist mir schleierhaft
Eben, du weißt nicht was "Laufzeit" ist. Dann würdest du nicht sagen, das Java alle möglichen Strings abdeckt.
es gibt nicht einen string für alles wie in Java
Java hat nur EINEN Laufzeit-String, und das ist ein UTF-16-String!!! Nichts mit "alles abdecken"! Wenn du UTF-8-XML rausschreibst, konvertiert die XML-Library die Java-UTF-16-Strings für den einen Moment nach UTF-8. Wenn du einen XML-UTF-8-Value in einen Java-String lädst, ist der ehem. UTF-8-String zur Java-Laufzeit ein UTF-16-String.
Wenn die C++-Leute lieber std::string und nicht std::wstring benutzen, dann kann C++ nichts dafür. wstring ist das C++-Pendant zum Java-String. Ich benutze nur noch std::wstring, und für rein technische Zeichenketten vielleicht std::string.
wenn ein Programm einen string in utf-8 habenm will, dann muss ich halt konvertieren.
Javas String kann bzgl. Unicode nicht wirklich mehr als wstring. Oder zeig mir bitte wo java.lang.String eine UTF-8-Konvertierung anbietet???
-
Hallo,
UTF-8 ist ein Kompressionsformat für Unicode. Der Trick dabei ist, daß alle ASCII-Zeichen (0 - 127) unkomprimiert gespeichert werden. Wenn Linux intern UTF-8 verwendet, dann ist das kein großer Nachteil, da bei ASCII-Zeichen nichts dekodiert werden muß und daher auch keine Nachteile zur Laufzeit auftreten.Außerdem kann man mit UTF-8 wesentlich mehr Zeichen speichern, als mit dem primitiven UTF-16 Format.
-
Schön, es gibt dann keinen Performance-Nachteil, wenn man nur ASCII-Zeichen benutzt. Typisch: es gibt nur Amerikaner auf der Welt. Was ist mit arabischen, hibräischen, ungarischen, russischen, japanischen u.a. Anwendungen? Viel Spaß beim codieren und decodieren, wenn diese ausserhalb von ASCII liegen.
Was meinst du, warum Solaris, NT, Java und MacOS X u.a. doch lieber UTF-16 haben? Nicht zufällig, um in den meistgenutzten Zeichensätzen eine optimale Performance zur Laufzeit zu haben? Kann man auch auf unicode.de nachlesen, das zur Laufzeit lieber UTF-16 oder am besten gleich UTF-32 genutzt werden soll. Für den Datenaustausch macht UTF-8 Sinn, um in 8bit-Streams meine Strings speichern/senden zu können.
Außerdem kann man mit UTF-8 wesentlich mehr Zeichen speichern, als mit dem primitiven UTF-16 Format.
Primitiv?
Will darauf nicht eingehen. Laut unicode-FAQ ist UTF-16 für alle gängigen Sprachen dieser Welt ausreichend. Damit habe ich zumindest alle alltäglichen Zeichensätze dieser Welt erstmal abgedeckt. Will ich mehr abdecken, benutze ich zur Laufzeit UTF-32.
-
Ich löse mich mal kurz von der UTF-Foobar Thematik...
ManOMan schrieb:
es gibt nicht einen string für alles wie in Java
yepp, java.lang.String ist gut. Aber wenn man z.B. nicht weiß dass man für Strings, die häufig verändert werden, doch lieber StringBuffer nimmt, dann schießt man sich mit java.lang.String und vielen appends usw. ziemlich ins Knie.
Während java.lang.String für Threading super ist, ist er für viele Veränderungen schlecht. Umgekehrt gilt das gleiche für den StringBuffer.
Nicht dass ich jetzt std::string verteidigen will (die Klasse haut einen jetzt echt nicht um), aber es ist halt nicht immer alles Gold, was glänzt.
-
OK, wenn man Unicode ausser Acht lässt und String-Verarbeitung im großen Masse betreibt, benutze ich StringBuffer. Seit Java 1.5 gibts sogar einen dritten String: StringBuilder.
-
Artchi schrieb:
Laut unicode-FAQ ist UTF-16 für alle gängigen Sprachen dieser Welt ausreichend. Damit habe ich zumindest alle alltäglichen Zeichensätze dieser Welt erstmal abgedeckt. Will ich mehr abdecken, benutze ich zur Laufzeit UTF-32.
Dir ist aber schon klar, daß du damit sehr viel Speicher verschwendest?
Bei UTF-32 sind es mal eben 25 Bits pro Zeichen, die unbenutzt sind, wenn Strings nur Zeichen enthalten, die auch im ASCII-Format darstellbar sind.
Außerdem ist die Dekompression von UTF-8 relativ "straight forward". Es ist nicht so, daß dazu wahnsinnig viel Rechenzeit geopfert werden muß, wie man vielleicht denken könnte, wenn man deine Beiträge hier liest.
-
Artchi schrieb:
Was du mit "zur Laufzeit" willst ist mir schleierhaft
Eben, du weißt nicht was "Laufzeit" ist. Dann würdest du nicht sagen, das Java alle möglichen Strings abdeckt.
es gibt nicht einen string für alles wie in Java
Java hat nur EINEN Laufzeit-String, und das ist ein UTF-16-String!!! Nichts mit "alles abdecken"! Wenn du UTF-8-XML rausschreibst, konvertiert die XML-Library die Java-UTF-16-Strings für den einen Moment nach UTF-8. Wenn du einen XML-UTF-8-Value in einen Java-String lädst, ist der ehem. UTF-8-String zur Java-Laufzeit ein UTF-16-String.
Wenn die C++-Leute lieber std::string und nicht std::wstring benutzen, dann kann C++ nichts dafür. wstring ist das C++-Pendant zum Java-String. Ich benutze nur noch std::wstring, und für rein technische Zeichenketten vielleicht std::string.
Ahh, mit zur Laufzeit meinst du die interne darstellung. Was ich eigentlich mit "einen string für alles" mein, ist das man in C++ ständig andere hat. Jedes Framework hat nen anderen CString, std::(w)string, BSTR....
wenn ein Programm einen string in utf-8 habenm will, dann muss ich halt konvertieren.
Javas String kann bzgl. Unicode nicht wirklich mehr als wstring. Oder zeig mir bitte wo java.lang.String eine UTF-8-Konvertierung anbietet???
String
public String(byte[] bytes,
String charsetName)
throws UnsupportedEncodingExceptionConstructs a new String by decoding the specified array of bytes using the specified charset. The length of the new String is a function of the charset, and hence may not be equal to the length of the byte array.
The behavior of this constructor when the given bytes are not valid in the given charset is unspecified. The CharsetDecoder class should be used when more control over the decoding process is required.
Parameters:
bytes - the bytes to be decoded into characters
charsetName - the name of a supported charsetUnd bei charset:
Standard charsets
Every implementation of the Java platform is required to support the following standard charsets. Consult the release documentation for your implementation to see if any other charsets are supported.
Charset
Description
US-ASCII Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set
ISO-8859-1 ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
UTF-8 Eight-bit UCS Transformation Format
UTF-16BE Sixteen-bit UCS Transformation Format, big-endian byte order
UTF-16LE Sixteen-bit UCS Transformation Format, little-endian byte order
UTF-16 Sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order markUnd mit getBytes in die andere richtung.
-
Dir ist aber schon klar, daß du damit sehr viel Speicher verschwendest?
Bei UTF-32 sind es mal eben 25 Bits pro Zeichen, die unbenutzt sind, wenn Strings nur Zeichen enthalten, die auch im ASCII-Format darstellbar sind.
Außerdem ist die Dekompression von UTF-8 relativ "straight forward". Es ist nicht so, daß dazu wahnsinnig viel Rechenzeit geopfert werden muß, wie man vielleicht denken könnte, wenn man deine Beiträge hier liest.Und wer sagt, das deine Software hauptsächlich aus ASCII-Zeichen besteht? In Amerika und England mag die Software dann nur ASCII haben. Außerhalb dieser zwei Welten schon nicht mehr.
Du kannst ja gerne UTF-8 zur Laufzeit benutzen, wenn du eine passende String-Klasse hast. Will ich dir ja nicht wegnehmen. Nur Fakt ist: kein mir bekanntes System ausser Linux benutzt UTF-8 zur Laufzeit. Ob es schlecht oder gut ist, steht nicht zur Diskussion. Zur Diskussion steht, ob C++' std::wstring aus der Reihe tanzt? Und das tut es nunmal nicht.
-
ManOMan schrieb:
Ahh, mit zur Laufzeit meinst du die interne darstellung. Was ich eigentlich mit "einen string für alles" mein, ist das man in C++ ständig andere hat. Jedes Framework hat nen anderen CString, std::(w)string, BSTR....
Ja, aber nochmal: dafür kann ISO-C++ nichts. wstring gibts seit 1998 bei der ISO. wxString, QString, CString usw. sind weit vor 1998 entstanden. Wenn die Framework-Urheber nicht auf wstring umspringen, ist das nicht ein Problem von C++.
Microsofts gesamte API arbeitet heute anstandslos mit wstring bzw. wchar_t* zusammen, ohne das man als C++-Programmierer seine wstrings konvertieren muß.
Die GDI+ z.B. arbeitet ausschliesslich nur noch mit diesem String-Typ zusammen. Hier hat MS ausnahmsweise auf ISO-C++-kompatibilität umgestellt. Obwohl viele MS immer wieder keine Standards vorwerfen. Aber da haben vielen OpenSource-Projekte was nachzuholen.Wenn andere Libs nicht mit wstring arbeiten, ist das keine C++-Schuld. Man muß differenzieren. MS hat den Umstieg heute durchgezogen und ist aus dem Schneider.
ManOMan schrieb:
Und mit getBytes in die andere richtung.
Stimmt, hab vergessen das man bei den Bytes den Typ angeben kann. Sorry.
Aber die Laufzeit ist davon nicht betroffen. Wenn ich in C++ einen wstring z.B. als UTF-8 rausschreiben will, mache ich sowas:
#include <fstream> #include <locale> #include "Dinkum/codecvt/wbuffer" #include "Dinkum/codecvt/utf8" ..... { // write Hello as one line to a file std::ofstream bytestream("myfile.txt"); // open file as byte stream Dinkum::codecvt::wbuffer_convert< Dinkum::codecvt::codecvt_utf8<wchar_t> > mybuf(bytestream.rdbuf()); // construct wide stream buffer object std::wostream mystr(&mybuf); // construct wide ostream object mystr << L"Hello" << std::endl; }Das Defizit bei C++ ist, das die utf8-Facate im ISO nicht vorgeschrieben ist. Aber man kann beliebige Facets einbinden, in dem man eine andere codecvt-Implementierung nimmt, was analog zu den Java-Byte-String-Konvertierungen ist.
Habe ein Bild dazu gezeichnet:
http://www.kharchi.de/codecvt.png
-
Andromeda schrieb:
Dir ist aber schon klar, daß du damit sehr viel Speicher verschwendest?
Das ist doch für 99% der Anwendungen vollkommen irrelevant! Dann verbraucht man eben (maximal) doppelt soviel Speicher, na und? Das ist ein konstanter Faktor, das ist vollkommen nebensächlich? Wann braucht man denn mal so große Strings, dass das eine Rolle spielt?
(Ich weiß wann: Ich selbst verwende std::string in der Bioinformatik um chemische Sequenzen darzustellen, hier wäre std::wstring wirklich fehl am Platze. Aber für alles verwende ich std::wstring).