2010-11-10 7 views
6

Es ist schon eine Weile her, dass ich in C++ programmiert habe und ich denke, die meisten Programmierer in C++ würden zustimmen, dass eine der kniffligsten Entscheidungen darin besteht, aus einer fast schwindelerregenden Anzahl verfügbarer Stringtypen zu wählen. Ich bevorzuge ATL Cstring wegen seiner Benutzerfreundlichkeit und Funktionen, möchte aber eine vergleichende Studie der verfügbaren Optionen. Ich habe SO ausgecheckt und habe keinen Inhalt gefunden, der die Auswahl der richtigen Zeichenfolge unterstützt. Es gibt Websites, die Konvertierungen von einer Zeichenfolge zur anderen angeben, aber das ist nicht das, was wir hier wollen.C++ Strings, wann was zu verwenden?

Würde gerne einen Vergleich basierend auf Spezialität, Leistung, Portabilität (Windows, Mac, Linux/Unix, etc), Benutzerfreundlichkeit/Funktionen, mehrsprachige Unterstützung (Unicode/MBCS), Nachteile (falls vorhanden), und alle anderen speziellen Fälle.

Ich lese die Strings auf, die ich bisher gefunden habe. Ich glaube, es würde mehr geben, also können wir das später bearbeiten, um andere Optionen zu berücksichtigen. Wohlgemerkt, ich habe vor allem unter Windows gearbeitet, so spiegelt die Liste das gleiche:

  1. char*
  2. std::string
  3. basic_string der STL
  4. CString ATL
  5. MFC CString
  6. BSTR
  7. _bstr_t
  8. CComBstr
+0

Verwenden Sie sie alle. Du wirst sowieso mit allen drin sein, also versuche nicht, am Anfang wählerisch zu sein. –

+1

Verwende 'CComBstr' nur, wenn du mit COM arbeitest. –

+0

Sie könnten ICU-Strings in den Mix für eine ordnungsgemäße Unicode-Behandlung hinzufügen. –

Antwort

7

Bedeuten nicht, einen Dämpfer auf Ihre Begeisterung für diese setzen, aber es ist realistisch ineffizient viele String-Typen in einem Projekt zu mischen, so desto größer wird das Projekt mehr die unweigerlich sollte es siedeln sich auf std :: string (das ist ein typedef zu einer Instanziierung von STLs basic_string für den Typ char, nicht eine andere Entität), da dies die einzige semantische Standardoption ist. char * ist ok, hauptsächlich für Strings mit fester Größe (z. B. Stringliterale, Puffer fester Größe) oder Schnittstelle mit C.

Warum sage ich, dass es ineffizient ist? Sie erhalten unnötige Template-Instanziierungen für die verschiedenen String-Argumente (Permutationen sogar für mehrere Argumente). Sie finden, dass Sie Funktionen aufrufen, die ein Ergebnis in eine Zeichenfolge & laden möchten, dann müssen Sie .c_str() aufrufen und einen anderen Typ konstruieren, der redundante Speicherzuweisungen durchführt. Sogar const std :: string & erfordert eine Zeichenfolge temporär, wenn sie mit einem ASCIIZ char * aufgerufen wird (z. B. zu einem anderen Puffer des Stringtyps). Wenn Sie eine Funktion schreiben möchten, die den Typ des Strings behandelt, den ein bestimmter Aufrufer verwenden möchte, werden Sie zu Templates und damit zu Inline-Code, längeren Kompilierungszeiten und Neukompilierungsabhängigkeiten gezwungen (es gibt einige Möglichkeiten, dies zu mindern, aber sie werden komplex und um bequem oder automatisiert zu sein, neigen sie dazu, Änderungen an den verschiedenen String-Typen zu erfordern - zCasting-Operator oder Member-Funktion, die ein gemeinsames Interface/Proxy-Objekt zurückgibt).

Projekte müssen möglicherweise nicht standardmäßige Zeichenfolientypen verwenden, um mit Bibliotheken zu interagieren, die sie verwenden möchten. Sie möchten dies jedoch minimieren und die Verbreitung möglichst beschränken.

+0

Weitere Informationen zu 'std :: string 'und Unicode finden Sie [hier] (http://stackoverflow.com/questions/402283/stdwstring-vs-stdstring). –

2

Die traurige Geschichte von C++ String-Handling ist zu deprimierend für mich einen Aufsatz über, aber nur ein paar Punkte zu schreiben:

  • ATL und MFC CString die gleiche Sache ist (der gleiche Code und alles). Sie wurden vor Jahren zusammengelegt.

  • Wenn Sie entweder _bstr_t oder CComBstr verwenden, verwenden Sie wahrscheinlich BSTR nur bei Aufrufen in APIs anderer Personen, die BSTR verwenden.

+0

@ Will - Danke. Das hilft. –

1

Offensichtlich sind nur die ersten drei portabel, daher sollten sie in den meisten Fällen bevorzugt werden. Wenn Sie C++ ausführen, sollten Sie in den meisten Fällen char * vermeiden, da rohe Zeiger und Arrays fehleranfällig sind. Eine Ausnahme bildet die Anbindung an Low-Level-C, beispielsweise in Systemaufrufen oder Treibern. std:string sollte standardmäßig bevorzugt werden, IMHO, weil es so gut mit dem Rest der STL ineinander greift.

Wieder IMHO, wenn Sie mit z. MFC, Sie sollten mit allem wie std::string in Ihrer Geschäftslogik arbeiten und in und von CString übersetzen, wenn Sie die WinApi-Funktionen treffen.

+1

Ich denke, du wolltest schreiben * sollte nicht 'char *' *? –

+0

@Space: Danke! –

2
  • char* - schnelle, Funktionen schließen diejenigen ein, die in < cstring sind> Header, fehleranfällig (zu Low-Level)

  • std::string - das ist eigentlich ein typedef für std::basic_string<char, char_traits<char> > Eine schöne Sache - zuerst von allem ist es auch schnell. Zweitens können Sie alle <-Algorithmen> s verwenden, da basic_string Iteratoren bereitstellt. Für die Breitzeichenunterstützung gibt es einen anderen Typdef, wstring, der std::basic_string<wchar_t, char_traits<wchar_t> > ist. Dies ist ein Standard-Typ (basic_string) ist daher absolut portabel. Ich würde mit diesem gehen.

  • ATLs und MFCs CStrings stellen nicht einmal Iteratoren zur Verfügung, deshalb sind sie für mich ein Gräuel, weil sie ein Class-Wrapper um C-Strings sind und sehr schlecht entworfen sind. IMHO

  • weiß nicht über den Rest.

Hoffen, dass diese Teilinformationen hilft

+0

Danke. Das hilft wirklich. –

1

2 und 3 sind die gleichen. 4 und 5 sind auch gleich. 7 und 8 sind Wrapper von 6. So enthält die Liste nur C-Strings, C++ - Standardstrings, Microsofts C++ - Strings und Microsofts COM-Strings. Das gibt Ihnen die Antwort: Verwenden Sie in C++ Standard C++ - Zeichenfolgen (std::string)