"内部"与"关联"流缓冲区的区别

10

http://www.cplusplus.com/reference/ios/ios/rdbuf/

一些派生的流类(例如stringstream和fstream)维护自己的内部流缓冲区,并在构造时与其关联。调用此函数更改关联流缓冲区对该内部流缓冲区没有影响:流将具有与其内部流缓冲区不同的关联流缓冲区(虽然流上的输入/输出操作总是使用由此成员函数返回的关联流缓冲区)。

并且在http://www.cplusplus.com/reference/fstream/ifstream/rdbuf/上:

返回指向内部filebuf对象的指针。

但是请注意,这不一定与当前关联的流缓冲区相同(由ios::rdbuf返回)。

那么如果它不用于输入和输出操作,那么内部缓冲区是用来做什么的呢?如果意味着这两行代码可以返回两个不同的对象,那么这可能有什么用处呢?

std::stringstream ss;
ss.rdbuf();                          // (1) returns "internal" stream buffer?
static_cast<std::ios&>(ss).rdbuf();  // (2) returns "associated" stream buffer?

1
但是,这不是很违反直觉吗?ifstream::rdbuf()返回的并不是对象当前使用的缓冲区? - Felix Dombek
这就是 ios::rdbuf 的作用。 - Sam Varshavchik
1
@FelixDombek 我还没有读完你的问题,但如果你在问iostream是否有一些反直觉的地方,答案可能是肯定的。如果下一个问题是从头开始进行完全重新设计是否会使它变得更好,那么答案就更加肯定了。 - curiousguy
1个回答

4

内部缓冲区用于输入和输出操作,直到使用其他参数调用rdbuf为止,然后它就会保持不变。

您可以通过调用以下方法重新启用它:

stream.basic_ios::rdbuf(stream.rdbuf());

请注意,例如std::fstream的内部缓冲区始终是一个由流对象拥有和管理的std::filebuf对象,而关联缓冲区可以是任何streambuf派生对象。流仅存储对它的基类指针,不管理其生命周期。
还要注意,标准没有使用术语“内部缓冲区”。标准使用了略有不同的术语:

basic_ifstream<charT, traits>支持从命名文件中读取。它使用一个basic_filebuf<charT, traits>对象来控制关联序列。为了阐述,这里介绍了维护的数据:

sb,即filebuf对象。

上面的“维护的数据”就是cplusplus.com所称的“内部流缓冲区”。

“内部流缓冲区”可能比“维护的数据”更易于理解和更直观。” - curiousguy
谢谢!basic_ios::这部分真的需要吗? - Felix Dombek
3
是的,fstream::rdbuf() 隐藏了 basic_ios::rdbuf 两个重载函数,因此您需要显式访问它们。 - n. m.
那么,如果我们不手动更改相关的流缓冲区,内部流缓冲区是否与相关的流缓冲区相同? - xskxzr
@xskxzr 是的,完全正确。 - n. m.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接