为什么在“std”中添加了“ifstream”和“ofstream”,而“fstream”可以同时实现这两个目的?

10
使用 `std::fstream` 可以声明两种类型的对象:`ifstream` 和 `ofstream`。唯一的区别是,在 `fstream` 中我们需要将 `in`、`out`、`app` 作为参数提供,而在其他两个类型中并不总是需要。关于 `ifstream`、`ofstream` 是否有什么特殊之处,不能通过 `fstream` 实现还是只是编码上的方便,请问?
3个回答

16

这有点像问我们为什么要使用const,而你仍然可以从变量中读取和写入。它允许在编译时进行检查,这是减少错误的宝贵功能。而且它更容易理解,当查看没有构造函数调用的声明时,您可以看到它是输入、输出还是两者都有:您提到的参数通常只能在实现文件中看到,可能不方便使用。此外,每种类型的流可能会有一些差异,它们需要的数据成员-潜在地使用与您实际需求相匹配的最小功能类可节省内存,在初始化或检查那些其他变量等方面耗费时间。


4

如果说有什么区别,fstream 只是一种方便的工具。具体来说,你所拥有的基本上就是:

namespace std { 
class ifstream { /* ... */ };

class ofstream { /* ... */ };

class fstream : public ifstream, public ofstream { /* ... */ };
}

[显然跳过了许多无关的细节].

简而言之,fstream 通过从 ifstreamofstream 派生出来,提供了所有 ifstream 的输入功能和所有 ofstream 的输出功能。如果没有 ifstreamofstream,那么一个类似于 fstream(至少在其当前形式下)的东西根本无法存在。


1
你忽略的一个无关细节是它事实上是错误的。fstream(实际上是basic_fstream<char>)既不继承自ifstream也不继承自ofstream。 - DanielKO
3
@DanielKO说的没错,但是确实无关紧要。如果您想要技术上的解释,ifstream继承自istream,而ofstream则继承自ostream。fstream继承自iostream,后者又同时继承自istream和ostream(当然,为了技术上的准确性,我们应该在各处添加不同的“std::”和“basic_”前缀及“<char>”后缀)。您真的认为排除那些您自己都承认是无关紧要的细节是下投票的充分理由吗? - Jerry Coffin
但是你在暗示fstream微不足道地继承了ifstream和ofstream的实现,就好像fstream只是另外两个的粘合剂一样。你不应该过分简化你的回答,以至于它不能反映事实。我忘记引用“无关细节”这一点来强调讽刺,对此我感到抱歉。 - DanielKO
1
@DanielKO:你能指出在简化中实际上失去了什么相关的东西吗?现实情况是,fstream相当简单,而且它基本上只是胶水。最糟糕的是,你可以说这个胶水在 "方向" 上略有不同,基本上是将iostream粘合到文件流输入和输出缓冲区中,而不是直接转到ifstream和ofstream。深入探讨这一点会使答案变得很长,但并没有添加实质性内容。 iostream中间件主要是作为其他类(例如 stringstream)的基础而感兴趣的。 - Jerry Coffin
1
当然。void foo(std::ofstream& output); void bar() { std::fstream f("a"); foo(f); } - DanielKO
@DanielKO:这与ifstream和/或ofstream是否提供任何有用的东西和/或是否应该存在有什么关系呢? - Jerry Coffin

3

整个意图是通用性。如果你只需要读取一个文件,你可以将ifstream作为参数传入,然后任何支持读取的内容都可以被传递进来,即使它不可写。反之亦然。


2
我不明白这个答案与问题有任何关系。 - ildjarn
@Tony 是的,我刚注意到 ifstream 被强制提供一个 filebuf 对象,限制了替代实现的潜力。我认为编译时检查和自我文档化是更好的解释。 - Antimony

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