c++ - 为什么 iostream 不可复制?

标签 c++ iostream copy-constructor

possible使用 rdbufcopyfmt 创建 iostream 对象的本地拷贝。这允许格式更改在本地范围内:

std::ostream & operator << ( std::ostream & os, foo const & smth ) {
    cloned_ostream cs( os );
    cs << std::hex << smth.num;
    // os is not switched to hexadecimal, which would be a confusing side-effect
    return os;
}

为什么流类不提供复制构造函数来执行此操作?

相关的 C++ 最佳实践在设计为不可复制后是否发生了变化?

最佳答案

复制和移动是值语义操作。要定义它们,您首先必须确定类的哪些属性为其对象提供不同的值。这一点最初在 iostreams 库中基本上被回避了,然后 C++11 采取了与这种复制构造函数不兼容的不同方向。

流对象的状态包括两部分:指向流缓冲区及其关联状态的指针和格式化信息。自 C++98 起,rdbufrdstatecopyfmt 分别公开此信息。

从 C++11 开始,流类也有一个 protected 接口(interface),包括一个移动构造函数(和一个名为move的成员),它复制格式但不流缓冲区指针。这使 iostream 将格式化信息专门视为流对象的状态。

如果此时流可复制,它只会执行 copyfmt 而不会执行其他操作。

从值状态中排除 rdbuf 的选择可能是由于派生类的值语义更加困惑,例如 std::fstream,它不仅暴露访问流缓冲区,但也嵌入并拥有它。

std::ifstream f( path + filename ); // Owns, or even "is," a file.
std::istream i = f; // Observes an externally-managed file.

std::istream i2 = i; // OK, copy a shallow reference.
std::ifstream f2 = f; // Error, ifstream is more than a shallow reference.

std::istream i3 = std::move( f ); // Error? Would retain a reference to an rvalue.
std::ifstream f3 = std::move( f ); // OK: full copy including the file buffer.

语义在某种程度上可能是一致的,但适度的增益会造成很多困惑。

关于c++ - 为什么 iostream 不可复制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36051672/

相关文章:

java - 如何将键和鼠标事件发送到 Java 小程序?

c++处理来自输入文件的数据会创建无限循环

c++ - 有没有一种简单的方法来获取用 C++ 打印的字符数?

c++ - 在 C++ 中调用复制构造函数

c++ - 为什么赋值运算符重载会创建一个对象的拷贝?

C++ 在内存中按字节移动

c++ - 无法使用 sizeof(成员变量)在 Visual Studio 中初始化静态常量值

c++ - 在 C++ 中打印变量名的通用方法

c++ - C++:在数组中输入数字时,第一个数字为0

c++ - 自己调用拷贝构造函数