C++复制流对象
我一直在尝试C++,并且遇到了一个我不知道如何解决的问题。
基本上,我发现您无法复制流(请参阅 为什么不能复制 stringstream允许吗?),这也适用于“包裹”它们的对象。例如:
- 我创建一个具有 stringstream 类型的数据成员的类。
- 我创建了这个类的一个对象。
- 我尝试复制该对象,例如“TestObj t1; TestObj t2; t1 = t2;”
这会导致错误 C2249:
'std::basic_ios<_Elem,_Traits>::operator =':没有到虚拟基'std::basic_ios<_Elem,_Traits>'中声明的私有成员的可访问路径
所以我的问题是:如何(最好轻松)复制具有 *stream 类型数据成员的对象?
完整的示例代码:
#include <iostream>
#include <string>
#include <sstream>
class TestStream
{
public:
std::stringstream str;
};
int main()
{
TestStream test;
TestStream test2;
test = test2;
system("pause");
return 0;
}
提前致谢。
更新
感谢以下答案,我已经成功解决了这个问题。我所做的就是声明一次流对象,然后使用包装器对象(例如,TestStream)中的指针简单地引用它们。对于具有私有复制构造函数的所有其他对象也是如此。
I've been experimenting with C++, and I've come across a problem that I don't know how to solve.
Basically, I've discovered that you can't copy streams (see Why copying stringstream is not allowed?), and that also applies for objects that 'wrap' them. For example:
- I create a class with a data member of type stringstream.
- I create an object of this class.
- I attempt to copy the object, eg "TestObj t1; TestObj t2; t1 = t2;"
This causes the error C2249:
'std::basic_ios<_Elem,_Traits>::operator =' : no accessible path to private member declared in virtual base 'std::basic_ios<_Elem,_Traits>'
So my question is: how can I (preferably easily) copy objects that have data members of type *stream?
Full example 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;
}
Thanks in advance.
UPDATE
I've managed to solve this problem thanks the answers below. What I have done is declare the stream objects once and then simply reference them using pointers in the wrapper objects (eg, TestStream). The same goes for all other objects that have private copy constructors.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不允许您复制流的原因是 它不复制流是有意义的。如果你解释了你想要做什么,那么肯定有办法做到这一点。如果您想要可以复制的数据块,请使用字符串。但流更像是连接而不是字符串。
The reason you are not allowed to copy a stream is that it doesn't make sense to copy a stream. If you explain what it is that you are trying to do, there's certainly a way to do it. If you want a chunk of data you can copy, use a string. But a stream is more like a connection than a string.
本文提供了实现此目的的方法。但请注意有趣的总结:
This article provides ways to do it. Note however the interesting summary:
当然你必须自己编写复制构造函数和复制赋值运算符。
接下来,您必须决定您希望副本具有什么语义。因此:
如果您想要浅拷贝(
"foobar"
),那么您需要在TestStream
的多个实例之间共享 stringstream 对象,可能最好使用为此,使用shared_ptr
。如果您想要深层复制(
“foo”
),那么您可以像这样复制:或者使用您链接到的问题中的变体之一。
这涵盖了您在获取副本时正在写入的字符串流。如果您正在从中读取,或者如果您正在写入,但由于使用
seekp
,您可能没有写到最后,那么您需要捕获当前读/写位置以及字符串流中的数据,您可以使用tellg/tellp来完成此操作。您可能还想复制流的格式状态等,这就是 copyfmt 的作用,甚至是错误标志 (
rdstate
--copyfmt< /code> 让他们独自一人)。
Certainly you have to write the copy constructor and copy assignment operator yourself.
Next, you have to decide what semantics you would like the copy to have. So:
If you want a shallow copy, (
"foobar"
) then you need to share the stringstream object between multiple instances ofTestStream
, probably best to use ashared_ptr
for that.If you want a deep copy (
"foo"
), then you could copy like this:Or use one of the variants in the question you link to.
That covers a stringstream to which you're in the middle of writing when you take the copy. If you're in the middle of reading from it, or if you're writing but you might not be writing to the end because of use of
seekp
, then you need to capture the current read/write positions as well as the data in the stringstream, which you do withtellg/tellp
.You might also want to copy across the stream's format state, and so on, which is what
copyfmt
does, and even the error flags (rdstate
--copyfmt
leaves them alone).您可以做两件事,两者都涉及小心谁拥有该对象:
存储对流的引用,并确保只要您的这些类存在,该对象就不会超出范围。< /p>
复制指针,并确保仅在最后一个类完成指向的流对象时才删除。
两者是等效的,尽管我个人更喜欢参考方法。
There are two things you can do, both involve being careful about who owns the object:
Store a reference to a stream, and make sure the object does not go out of scope as long as these classes of yours are around.
copy the pointers around, and be sure to delete only when the last of your classes is done with the stream object pointed to.
Both are equivalent, although I personally prefer the reference approach.
为了测试 C++ 中各种写入操作的性能,这里有一段代码可以在您的计算机上编译,并使用多种方法测试有或没有缓冲的写入操作:
链接
To test the performance of various write operations in c++ here is a code which compiles on your machine and tests write operations with and without buffering with several methods:
Link