C++ - Kopie ein stream-Objekt
Ich habe experimentiert mit C++, und ich habe auf ein problem stoßen, dass ich nicht weiß, wie zu lösen.
Im Grunde, habe ich entdeckt, dass Sie nicht kopieren können-streams (siehe Warum das kopieren von stringstream ist nicht erlaubt?), und das gilt auch für Objekte, die 'wrap' Sie. Zum Beispiel:
- Ich erstelle eine Klasse ein Datenelement vom Typ stringstream.
- Erzeuge ich ein Objekt dieser Klasse.
- Ich versuchen, um das Objekt zu kopieren, z.B. "TestObj t1; TestObj t2; t1 = t2;"
Diese den Fehler verursacht C2249:
'std::basic_ios<_Elem,_Traits>::operator =' : Nein, Barrierefreier Weg, um private member deklariert virtual base 'std::basic_ios<_Elem,_Traits>'
Also meine Frage ist: wie kann ich (vorzugsweise leicht) Objekte kopieren, die Mitglieder-Daten des Typs *stream?
Vollständige Beispiel-code:
#include <iostream>
#include <string>
#include <sstream>
class TestStream
{
public:
std::stringstream str;
};
int main()
{
TestStream test;
TestStream test2;
test = test2;
system("pause");
return 0;
}
Vielen Dank im Voraus.
UPDATE
Habe ich es geschafft dieses problem zu lösen, Dank der Antworten unten. Was ich getan habe ist, erklären die stream-Objekte einmal und dann verweisen Sie einfach auf Sie mit Zeigern in der wrapper-Objekte (z.B. TestStream). Das gleiche gilt für alle anderen Objekte, die privaten copy-Konstruktoren.
- Da Sie scheinen Ihre Hausaufgaben gemacht haben, wird die verknüpfte Frage. Warum benötigen Sie dieses Verhalten? Lesen/schreiben?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Der Grund, Sie sind nicht erlaubt zu kopieren, ein stream ist, dass es macht keinen Sinn zu kopieren stream. Wenn Sie erklären, was es ist, dass Sie versuchen zu tun, es ist sicherlich ein Weg, es zu tun. Wenn Sie wollen, ein Stück von Daten, die Sie kopieren können, verwenden Sie eine Zeichenfolge. Aber ein stream ist eher eine Verbindung als ein string.
tellg
und mitseekg
später.Dieser Artikel bietet Möglichkeiten, es zu tun. Beachten Sie jedoch die interessante Zusammenfassung:
Sicherlich hast du zum schreiben der copy-Konstruktor und copy-Zuweisungsoperator selbst.
Als Nächstes müssen Sie entscheiden, welche Semantik Sie möchte die Kopie haben. Also:
Wenn Sie möchten, eine flache Kopie, (
"foobar"
), dann Sie teilen müssen, die stringstream-Objekt zwischen mehreren Instanzen vonTestStream
wahrscheinlich am besten verwenden Sie einshared_ptr
für, die.Wenn Sie möchten, eine Tiefe Kopie (
"foo"
), dann könnte man kopieren, wie diese:Oder verwenden Sie eine der Varianten in der Frage, die Sie verknüpfen.
Deckt ein stringstream, um die Sie sind in der Mitte der schreiben, wenn Sie die Kopie. Wenn Sie in der Mitte des Lesen aus, oder wenn Sie schreiben, aber Sie könnten nicht schreiben, um am Ende wegen der Verwendung von
seekp
, dann müssen Sie erfassen die aktuelle lese - /schreib-Position, sowie die Daten in den stringstream, die Sie tun, mittellg/tellp
.Vielleicht wollen Sie auch kopieren über das stream-format, Status, und so weiter, das ist, was
copyfmt
tut, und sogar die Fehler flags (rdstate
--copyfmt
lässt Sie allein).Gibt es zwei Dinge, die Sie tun können, sowohl vorsichtig darüber, wer das Objekt besitzt:
Speichern eine Referenz auf einen stream, und stellen Sie sicher, dass das Objekt nicht mehr gültig sind, solange diese Klassen von Ihnen sind rund.
kopieren Sie den Zeiger herum, und werden sicher erst dann zu löschen, wenn die Letzte der Klassen erfolgt mit dem stream-Objekt hinwies.
Beide sind gleichwertig, wobei ich persönlich lieber die reference-Ansatz.
boost::shared_ptr
geeignet ist (und auf jeden Fall vorzuziehen, um eine der alternativen).Testen Sie die Leistung verschiedener schreib-Operationen in c++, hier ist ein code, der kompiliert auf Ihrem Rechner und tests schreiben-Operationen mit und ohne Pufferung mit mehreren Methoden:
Link