为什么 iostream_withassign、ostream_withassign 和 istream_withassign 类 从 C++ I/O 系统中删除?

Why were the iostream_withassign, ostream_withassign & istream_withassign classes removed from the C++ I/O system?

在 C++98 之前,在 C++ I/O class 层次结构中有 3 个 classes 命名为 iostream_withassign, ostream_withassign & istream_withassign.

iostream_withassign的成员函数class:

构造函数和析构函数

~iostream_withassign

public:virtual ~iostream_withassign()

iostream_withassign

public:iostream_withassign()

创建一个 iostream_withassign 对象。它不对此对象进行任何初始化。

运算符=

public:iostream_withassign& operator =(iostream_withassign& rhs)

赋值运算符 运算符 =

过载 1

public:iostream_withassign& operator =(streambuf*)

此赋值运算符采用指向流缓冲对象的指针,并将此流缓冲对象与赋值运算符左侧的 iostream_withassign 对象相关联。

过载 2

public:iostream_withassign& operator =(ios&)

此赋值运算符采用对 ios 对象的左值引用,并将附加到此 ios 对象的流缓冲区与 iostream_withassign 对象左侧的对象相关联赋值运算符。

来源:this.

同样的方式 this 表示:

ostream_withassign class 是允许对象分配的 ostream 变体。预定义对象 cout、cerr 和 clog 是此 class 的对象,因此可以在 运行 时间重新分配给不同的 ostream 对象。例如,通常将输出发送到 stdout 的程序可能会被临时指示将其输出发送到磁盘文件。它还包含构造函数、析构函数和=(赋值)运算符函数。

不明白,为什么会有这些class?这3个class有用吗?为什么后来这 3 个 classes 从 C++98 标准中删除了?这是什么原因?

另见 C++ 流 class 层次结构。它没有这 3 classes.

他们发现有缺陷。它们被替换为:

  1. iostate rdstate() 读取流状态。
  2. void clear(iostate state = goodbit) 设置流状态。
  3. basic_streambuf<class charT, class Traits>* rdbuf() 检索流缓冲区。
  4. basic_streambuf<class charT, class Traits>* rdbuf(basic_streambuf<class charT, class Traits>* sb) 设置流缓冲区。
  5. basic_ios<class charT, class Traits>& copyfmt(basic_ios<class charT, class Traits>& rhs) 设置 rhs 的所有其他数据成员。

what's wrong with _withassign classes?

一致性。由于 C++98 标准 I/O 流被认为不会被复制,最初通过进行相关操作 private (直到 C++11)然后通过显式 delete-ing 它们.

在 C++ 中处理资源的方式很重要,因为您可以决定独占或共享它,这与在其他语言中您不能并且需要习惯所选择的语言不同。拥有两个版本会破坏(这是委婉的说法)一致性。这是违反直觉的。

此外,严格来说,*_withassign 包装器不会添加 iostreams 不能做的事情。


For example, a program that normally sends output to stdout could be temporarily directed to send its output to a disk file. It also contains constructor, destructor & =(assignment) operator functions.

您可以使用 rdbuf 获取流当前使用的基础 std::basic_streambuf 并提供另一个流,由另一个标准流获得或您通过继承 std::basic_streambuf class 就像 std::basic_filebuf 那样,例如。

您所说的可以通过以下方式轻松实现:

std::ofstream ofs{path};
auto oldbuf = cout.rdbuf( ofs.rdbuf() );