2015-09-23 13 views
19

Es gibt mehrere constructors für std::string. Ich suchte nach einer Möglichkeit, die Neuzuweisung zu vermeiden, und ich bin überrascht, dass es einen Füllkonstruktor gibt, aber keinen "Reserve" -Konstruktor.Warum gibt es keinen Reservierungskonstruktor für std :: string?

std::string (size_t n, char c); 

aber keine

std::string (size_t n); 

So habe ich reserve() zu nennen, nachdem er bereits den Standard (16 Bytes in meinem Fall) zugeordnet ist, nur sie sofort neu zu verteilen?

Gibt es einen Grund, warum es keinen solchen Konstruktor gibt, um Speicherplatz direkt beim Erstellen des Objekts zu reservieren, anstatt es manuell zu tun? Oder fehlt mir etwas und es gibt einen Weg, dies zu tun?

die Füllung Konstruktor ist eine Verschwendung von Zeit, weil es eine Schleife durch den Speicher nur überschrieben zu bekommen, und auch eine falsche Größe verursachen, weil s.length() berichtet N statt 0.

+0

Sind Sie sicher, dass 16 Bytes standardmäßig reserviert sind? ('sizeof (std :: string)' hat damit nichts zu tun) – deviantfan

+3

@deviantfan, das ist implementation-defined – SingerOfTheFall

+0

@SingerOfTheFall Ja, wie die 16 Byte auch. Ich meinte speziell Devolus Implementierung – deviantfan

Antwort

3

Das ist alles Rätselraten, aber ich werde es versuchen.

Wenn Sie bereits wissen, die Größe der Zeichenfolge, die Sie benötigen, werden Sie höchstwahrscheinlich Daten von woanders kopieren, z. aus einer anderen Zeichenfolge. In diesem Fall können Sie einen der Konstruktoren aufrufen, die char * oder const std::string & akzeptieren, um die Daten sofort zu kopieren.

Auch ich kann nicht sehen, warum reserve direkt nach dem Aufbau einer Zeichenfolge ist eine schlechte Sache. Während es die Implementierung definiert ist, würde ich davon aus, dass es sinnvoll, für diesen Code würde:

std::string str; 
str.reserve(100); 

Speicher für insgesamt 100 Elemente zuzuordnen, nicht 116 (wie in „16 zuzuteilen ersten, sie dann frei und zuteilen Sie 100 mehr "), also keinen Leistungseinfluss auf den nicht vorhandenen Reserve-Konstruktor.

Auch wenn Sie nur überhaupt eine leer Zeichenfolge ohne die Standardzuweisung möchten, können Sie vermutlich std::string str(0, ' '); verwenden, die die entkräftet „Mit dem fill Konstruktor ist eine Verschwendung von Zeit“ Punkt.

+0

Das 'std :: string str (0, '');' verhinderte die Standardzuweisung (VS2010). Ich habe festgestellt, dass dies in einem Debug-Build passiert, also wäre das kein Problem mehr, aber das war genau das, wonach ich gesucht habe. – Devolus

+0

Wenn 'std :: string' Ihnen eine anfängliche Kapazität vom Standardkonstruktor zur Verfügung stellt, liegt das daran, dass sie nur mit etwas Stack-Speicherplatz eingebaut sind. Es gibt nichts besonderes zu verteilen und zu löschen. –

0

Sie können grundsätzlich die gleiche Frage zu jeder std::string Methode stellen, die nicht als Konstruktor verkörpert ist.

zum Beispiel, warum haben wir nicht einen Konstruktor, der mehrere Zeichenketten nimmt und sie einzeln an die neu erzeugte Zeichenkette anhängt?

Es kann viele Gründe geben, einen Konstruktor nicht zu überladen, der einen Speicher reserviert. Ich denke, dass in einem Objektorientierten Setmind der Gedanke einer "reservierten Speicherkette" ein bisschen seltsam ist. Die Zeichenkette stellt eine Folge von Zeichen dar, nicht die dahinter liegende Erinnerung - das sind Implementierungsdetails, nicht das Hauptmerkmal.
Wenn jemand ein neues Restaurant eröffnet, denkt er sich: "Wenn dieses Restaurant endlich geöffnet ist, werde ich 100 Plätze für die angebliche 100-Personen-Gruppe reservieren, die kommen mag oder nicht!"

, aber Ihre Frage gibt implizit etwas sehr rigoros an: das Fehlen geeigneter Pufferobjekte in C++. Sie fragen nach Reserve-Konstruktor, weil Sie String als Puffer verwenden möchten, aber Null-Initialisierung ist sehr kostspielig.Wenn Sie den Speicher reservieren, können Sie nicht über die Zeichenfolgengröße hinaus schreiben.
so die Lösung für dieses Problem ist die Verwendung unique_ptr<char[]>, die nicht Null-initialisiert die Zeichen, aber wird Ihnen die RAII-Stil, den Sie suchen.

+0

Ich sehe nicht, wie ein unique_ptr-Objekt hier helfen würde, weil es mir die Funktionalität von std :: string nicht gibt. – Devolus

+0

Welche Funktionalität zum Beispiel? –

+0

Zum Beispiel: str + = txt; – Devolus

Verwandte Themen