Frage

Wann soll ich std::string und wann soll ich char* verwenden Arrays von chars in C ++ verwalten?

Es scheint, Sie char*, wenn die Leistung (Geschwindigkeit) von entscheidender Bedeutung verwenden sollten, ist, und Sie sind bereit, einige ein riskantes Geschäft zu akzeptieren, weil der Speicherverwaltung.

Gibt es andere Szenarien zu berücksichtigen?

War es hilfreich?

Lösung

Sie können std :: strings als Verweis übergeben, wenn sie groß sind, das Kopieren zu vermeiden, oder einen Zeiger auf die Instanz, so dass ich keinen wirklichen Vorteil mit char Zeiger sehen.

Ich benutze std :: string / wstring für mehr oder weniger alles, was eigentlichen Text ist. char * ist nützlich für andere Arten von Daten, obwohl und Sie können sicher sein, es freigegeben wird, wie es sollte. Ansonsten std :: vector ist der Weg zu gehen.

Es gibt wahrscheinlich Ausnahmen, um all dies.

Andere Tipps

Mein Standpunkt ist:

  • Nie char * verwenden, wenn Sie nicht als "C" -Code.
  • Verwenden Sie immer std :: string. Es ist einfacher, es ist freundlicher, es optimiert ist, ist es Standard, es Sie davon ab, Bugs zu verhindern, ist es worden ist geprüft und bewährt arbeiten

Raw-String Verwendung

Ja, manchmal wirklich Sie können dies tun. Wenn const char * verwenden, char-Arrays auf dem Stack und Stringliterale zugewiesen Sie es so machen kann überhaupt keine Speicherzuweisung ist.

so das Schreiben von Code erfordert oft mehr Denken und Pflege als String oder Vektor verwendet wird, aber mit richtigen Techniken kann es geschehen. Mit der richtigen Techniken kann der Code sicher sein, aber Sie müssen immer sicherstellen, wenn sie in char Kopieren [] entweder Sie haben einige Garantien für die Länge des Strings kopiert werden, oder Sie überprüfen und übergroße Saiten graziös handhaben. Nicht zu tun ist, was die strcpy Familie von Funktionen hat den Ruf unsicher zu sein.

Wie Vorlagen können sicher char Puffer helfen Schreiben

Wie für char [] Puffer Sicherheit, können Vorlagen helfen, da sie eine Kapselung für den Umgang mit der Puffergröße für Sie erstellen können. Vorlagen wie diese umgesetzt werden z.B. von Microsoft sicher Ersatz für strcpy zur Verfügung zu stellen. Das Beispiel hier ist von meinem eigenen Code extrahiert, hat der eigentliche Code viel mehr Methoden, aber das sollte genug sein, um die Grundidee zu vermitteln:

template <int Size>
class BString
{
  char _data[Size];

  public:
  BString()
  {
    _data[0]=0;
    // note: last character will always stay zero
    // if not, overflow occurred
    // all constructors should contain last element initialization
    // so that it can be verified during destruction
    _data[Size-1]=0;
  }
  const BString &operator = (const char *src)
  {
    strncpy(_data,src,Size-1);
    return *this;
  }

  operator const char *() const {return _data;}
};

//! overloads that make conversion of C code easier 
template <int Size>
inline const BString<Size> & strcpy(BString<Size> &dst, const char *src)
{
  return dst = src;
}

Eine Gelegenheit, die Sie char* verwenden müssen, und nicht ist std::string, wenn Sie statische String-Konstanten müssen. Der Grund dafür ist, dass Sie keine Kontrolle über den Auftrag Module ihre statischen Variablen zu initialisieren, und ein anderes globales Objekt aus einem anderen Modul zu der Zeichenfolge verweisen kann, bevor es initialisiert wird. http://google-styleguide.googlecode.com/svn/trunk/ cppguide.xml # Static_and_Global_Variables

std::string Profis:

  • verwaltet den Speicher für Sie (die Zeichenfolge wachsen kann, und die Umsetzung wird einen größeren Puffer Sie zuzuteilen)
  • Übergeordnetes Programmierschnittstelle, funktioniert gut mit dem Rest von STL.

std::string Nachteile: - zwei verschiedene STL-String-Instanzen können nicht die gleichen zugrunde liegenden Puffer teilen. Also, wenn Sie nach Wert übergeben bekommen Sie immer eine neue Kopie. -. Es einige Leistungseinbuße ist, aber ich würde sagen, es sei denn, Ihre Anforderungen speziell sind sie vernachlässigbar ist

Sie sollten sich überlegen char* in den folgenden Fällen zu verwenden:

  • wird dieses Array in Parameter übergeben werden.
  • Sie kennen die maximale Größe des Arrays im Voraus (Sie wissen es oder man verhängen es).
  • Sie werden keine Transformation in diesem Array tun.

Eigentlich in C ++, sind char* häufig verwendet für festes kleines Wort, wie Optionen, Dateiname, etc ...

Wenn ein c ++ std verwenden :: string:

  • Saiten, insgesamt sind sicherer als char *, Normalerweise, wenn man die Dinge mit char tun * Sie Dinge überprüfen müssen, dass die Dinge richtig, in der String-Klasse all dies geschieht für Sie.
  • machen Normalerweise
  • wenn char * verwenden, müssen Sie den Speicher frei Ihnen zugewiesen, Sie müssen nicht mit Zeichenfolge, die tun, da es seine internen Puffer freizugeben, wenn zerstört.
  • Strings arbeiten gut mit c ++ string, formatiert IO ist sehr einfach.

Wenn Zeichen verwenden *

  • Verwenden von char * gibt Ihnen mehr Kontrolle darüber, was „hinter“ die Kulissen geschieht, was bedeutet, können Sie die Leistung optimieren, wenn Sie benötigen.

Verwenden (const) char * als Parameter, wenn Sie eine Bibliothek schreiben. std :: string-Implementierungen unterscheiden sich zwischen den verschiedenen Compilern.

Wenn Sie C-Bibliotheken verwenden möchten, werden Sie mit C-Strings zu tun haben. Gleiches gilt, wenn Sie Ihre API C verfügbar machen möchten.

Sie können die meisten Operationen auf einem std :: string (wie zum Beispiel find) erwarten wie möglich optimiert werden, so dass sie wahrscheinlich mindestens so gut als reines C Pendant führen.

Es ist auch erwähnenswert, dass std :: string Iteratoren oft ganz auf Zeiger in das darunter liegende char-Array abzubilden. So dass jeder Algorithmus Sie oben auf Iteratoren ersinnen ist im Wesentlichen identisch mit dem gleichen Algorithmus auf der char * in Bezug auf Leistung.

Dinge zu achten gilt, sind z.B. operator[] - die meisten STL-Implementierungen nicht Grenzen Prüfung durchführen, und sollte dies auf dem darunterliegenden Zeichen-Array auf den gleichen Betrieb übersetzen. AFAIK STLPort kann optional Grenzen Prüfung durchführen, an welcher Stelle dieser Operator ein wenig langsamer sein würde.

Was also mit std :: string Sie gewinnen? Es entbindet Sie von der manuellen Speicherverwaltung; Ändern der Größe der Array wird einfacher, und Sie weniger zu befreien Speicher im Allgemeinen denken müssen.

Wenn Sie über die Leistung besorgt sind, wenn eine Zeichenfolge Ändern der Größe, es gibt eine reserve Funktion, die Sie nützlich finden können.

Wenn Sie das Array von Zeichen in wie Text usw. Verwendung std verwenden :: string flexibler und einfacher zu bedienen. Wenn Sie es für etwas anderes nutzen wie die Datenspeicherung? Verwendung Arrays (bevorzugen Vektoren)

Auch wenn die Leistung entscheidend ist, dass Sie eine bessere Nutzung vector<char> - es ermöglicht im Voraus Speicherzuweisung (Reserve () -Methode) und wird Ihnen helfen, Speicherlecks zu vermeiden. Unter Verwendung des Vektors :: operator [] führt zu einem Overhead, aber Sie können die Adresse des Puffers und indiziert immer genau extrahieren, wie wenn es ein Zeichen ist *.

AFAIK intern die meisten std :: string implementieren Copy on Write, Referenzsemantik gezählt Overhead zu vermeiden, auch wenn Strings nicht durch Verweis übergeben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top