length - char*vs std:: Zeichenfolge in C++




std::string (8)

Wann sollte ich std::string und wann sollte ich char* , um Arrays von char in C ++ zu verwalten?

Es scheint, dass Sie char* wenn die Leistung (Geschwindigkeit) entscheidend ist und Sie wegen der Speicherverwaltung einige riskante Geschäfte akzeptieren.

Gibt es noch andere zu berücksichtigende Szenarien?

https://code.i-harness.com


Verwendung der Raw-Zeichenfolge

Ja, manchmal kann man das wirklich tun. Wenn Sie const char *, char-Arrays, die auf dem Stack zugewiesen sind, und String-Literale verwenden, können Sie dies so tun, dass überhaupt keine Speicherzuweisung erfolgt.

Das Schreiben eines solchen Codes erfordert oft mehr Nachdenken und Sorgfalt als die Verwendung von Zeichenketten oder Vektoren, aber mit geeigneten Techniken kann es gemacht werden. Mit geeigneten Techniken kann der Code sicher sein, aber Sie müssen immer sicherstellen, dass beim Kopieren in char [] Sie entweder einige Garantien für die Länge der zu kopierenden Zeichenkette haben, oder Sie prüfen und handhaben übergroße Zeichenketten elegant. Dies nicht zu tun, hat der Familie der Funktionen den Ruf gegeben, unsicher zu sein.

Wie Vorlagen dazu beitragen können, sichere Zeichenpuffer zu schreiben

Wie bei der Sicherheit von char [] Buffern können Vorlagen helfen, da sie eine Kapselung für die Handhabung der Puffergröße für Sie erstellen können. Vorlagen wie diese werden zB von Microsoft implementiert, um einen sicheren Ersatz für strcpy zu bieten. Das Beispiel hier ist aus meinem eigenen Code extrahiert, der echte Code hat 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;
}

AFAIK intern am meisten std :: string implementieren Kopie auf schreiben, Referenz gezählt Semantik Overhead zu vermeiden, auch wenn Strings nicht durch Referenz übergeben werden.


Eine Gelegenheit, die Sie verwenden müssen char * und nicht std :: string ist, wenn Sie statische String-Konstanten benötigen. Der Grund dafür ist, dass Sie keine Kontrolle über die Auftragsmodule haben, um ihre statischen Variablen zu initialisieren, und ein anderes globales Objekt aus einem anderen Modul möglicherweise auf Ihre Zeichenfolge verweist, bevor sie initialisiert wird. http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Static_and_Global_Variables

Std :: String-Profis:

  • verwaltet den Speicher für Sie (der String kann wachsen, und die Implementierung wird Ihnen einen größeren Puffer zuweisen)
  • Übergeordnete Programmierschnittstelle, funktioniert gut mit dem Rest von STL.

std :: string cons: - zwei verschiedene STL-String-Instanzen können nicht denselben zugrunde liegenden Puffer gemeinsam nutzen. Wenn Sie also an Wert übergeben, erhalten Sie immer eine neue Kopie. - Es gibt eine Leistungseinbuße, aber ich würde sagen, wenn Ihre Anforderungen nicht speziell sind, ist es vernachlässigbar.


Mein Standpunkt ist:

  • Verwenden Sie niemals char *, wenn Sie nicht den "C" -Code aufrufen.
  • Verwenden Sie immer std :: string: Es ist einfacher, es ist freundlicher, es ist optimiert, es ist Standard, es wird Sie davon abhalten, Fehler zu haben, es wurde überprüft und bewiesen, dass es funktioniert.

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

Ich verwende std :: string / wstring für mehr oder weniger alles, was tatsächlicher Text ist. char * ist jedoch nützlich für andere Arten von Daten und Sie können sicher sein, dass es freigegeben wird, wie es sollte. Ansonsten ist std :: vector der richtige Weg.

Zu all dem gibt es wahrscheinlich Ausnahmen.


Sie sollten char* in folgenden Fällen verwenden:

  • Dieses Array wird in Parameter übergeben.
  • Sie wissen im Voraus die maximale Größe Ihres Arrays (Sie wissen es oder Sie erzwingen).
  • Sie werden keine Transformation für dieses Array durchführen.

In C ++ wird char* oft für feste kleine Wörter verwendet, wie Optionen, Dateiname, etc ...


Wenn Sie C-Bibliotheken verwenden wollen, müssen Sie mit C-Strings arbeiten. Gleiches gilt, wenn Sie Ihre API für C freigeben möchten.


Wenn Sie das Array von Zeichen in ähnlichem Text usw. verwenden, verwenden Sie std :: string flexibler und einfacher zu verwenden. Wenn Sie es für etwas anderes wie Datenspeicher verwenden? Verwenden Sie Arrays (bevorzugen Sie Vektoren)







arrays