C++ de la copie d'un objet de flux de données
J'ai fait des expériences avec le C++, et j'ai rencontré un problème que je ne sais pas comment le résoudre.
En gros, j'ai découvert que vous ne pouvez pas copier des cours d'eau (voir Pourquoi la copie stringstream n'est pas autorisé?), et qui s'applique également pour les objets de type "wrap". Par exemple:
- J'ai créer une classe avec un membre de données de type stringstream.
- - Je créer un objet de cette classe.
- Je tente de copier l'objet, par exemple "TestObj t1; TestObj t2; t1 = t2;"
Cela provoque l'erreur C2249:
'std::basic_ios<_Elem,_Traits>::operator =": pas de chemin accessible aux membre privé déclaré en base virtuelle 'std::basic_ios<_Elem,_Traits>'
Donc ma question est: comment puis-je (de préférence facilement) copie d'objets qui ont des membres de données de type *stream?
Exemple complet de 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;
}
Merci d'avance.
Mise à JOUR
J'ai réussi à résoudre ce problème merci les réponses ci-dessous. Ce que j'ai fait est de déclarer les objets de flux une fois et ensuite il suffit de faire référence à eux en utilisant des pointeurs dans l'emballage d'objets (par exemple, TestStream). Il en va de même pour tous les autres objets qui ont de la copie privée des constructeurs.
OriginalL'auteur Matt Larsen | 2011-10-26
Vous devez vous connecter pour publier un commentaire.
La raison pour laquelle vous n'êtes pas autorisé à copier un ruisseau, c'est que il ne fait pas de sens pour copier un flux. Si vous expliquer ce que c'est que vous êtes en train de faire, il y a certainement une façon de le faire. Si vous voulez un bloc de données, vous pouvez copier, utiliser une chaîne de caractères. Mais un flux est plus comme une connexion qu'une chaîne de caractères.
Qui n'a pas de sens en général. Que peut faire sens pour certains types de cours d'eau, mais comme une caractéristique générale d'un cours d'eau, il n'est pas raisonnable.
Je crois que j'ai trouvé ce dont j'ai besoin (oui, c'était pour istreams uniquement) - mémorisation de l'actuel flux de position avec
tellg
et à l'aide deseekg
plus tard.Attention, seekg() et seekp() déplacer la position parfois conjointement et parfois non, selon le type de flux que vous utilisez.
OriginalL'auteur David Schwartz
Cet article fournit les moyens de le faire. Toutefois, de noter l'intéressante synthèse:
OriginalL'auteur JRL
Certainement vous devez écrire le constructeur de copie et l'opérateur d'assignation de copie vous-même.
Ensuite, vous devez décider ce que la sémantique vous souhaitez que la copie d'avoir. Donc:
Si vous voulez une copie superficielle, (
"foobar"
), alors vous avez besoin de partager la stringstream objet entre plusieurs instances deTestStream
, probablement préférable d'utiliser unshared_ptr
.Si vous voulez une copie en profondeur (
"foo"
), puis vous pouvez copier comme ceci:Ou utiliser l'une des variantes dans la question que vous liez.
Qui couvre une stringstream à laquelle vous êtes dans le milieu de écrit lorsque vous prenez la copie. Si vous êtes dans le milieu de lecture, ou si vous écrivez, mais vous pourriez ne pas être écrit à la fin en raison de l'utilisation de
seekp
, alors vous avez besoin pour capturer le courant de lecture/écriture des positions en tant que bien que les données de la stringstream, ce que vous faites avectellg/tellp
.Vous pouvez aussi copier à travers le ruisseau du format de l'état, et ainsi de suite, ce qui est le
copyfmt
n', et même les indicateurs d'erreur (rdstate
--copyfmt
laisse seul).OriginalL'auteur Steve Jessop
Il y a deux choses que vous pouvez faire, les deux impliquent d'être prudent au sujet de qui est propriétaire de l'objet:
Stocker une référence à un cours d'eau, et assurez-vous que l'objet n'est pas hors de portée, tant que ces classes de la vôtre.
copier les pointeurs autour, et assurez-vous de supprimer uniquement lorsque le dernier de vos cours est fait avec le flux de l'objet pointé.
Les deux sont équivalents, même si personnellement je préfère la méthode de référence.
d'accord. Ceci est un cas où
boost::shared_ptr
est approprié (et certainement préférable à toutes les autres solutions).OriginalL'auteur rubenvb
Pour tester les performances des différentes opérations d'écriture en c++ voici un code qui compile sur votre machine et les tests des opérations d'écriture avec et sans mise en mémoire tampon avec plusieurs méthodes:
Lien
OriginalL'auteur Gabriel