为什么我不能使用`fstream`的实例初始化对`ofstream` /`ifstream`的引用?

时间:2014-06-06 07:21:32

标签: c++ reference fstream ifstream ostream

引言

void  read_foo (std::ifstream& out);
void write_foo (std::ofstream& out);

我有这两个函数,其中一个应该从文件中读取,另一个应该写入一个。

所有内容都有以下片段;

std::ifstream ifs ("filename.txt");
read_foo  (ifs);

std::ofstream ofs ("filename.txt");
write_foo (ofs);

问题

但是,如果我尝试使用std::fstream,那么我可以使用相同的流调用这两个函数,它不会编译,并且编译器会发出大量错误消息。

  • 为什么我无法将fstream绑定到ifstream&ofstream&

Foo.cpp中

#include <fstream>

void  read_foo (std::ifstream& out);
void write_foo (std::ofstream& out);

int main () {
  std::fstream fs ("filename.txt");

   read_foo (fs);
  write_foo (fs);
}

错误(S):

  


foo.cpp: In function ‘int main()’:
foo.cpp:9:16: error: invalid initialization of reference of type ‘std::ifstream& {aka std::basic_ifstream<char>&}’ from expression of type ‘std::fstream {aka std::basic_fstream<char>}’ read_foo (fs);
^
foo.cpp:3:7: note: in passing argument 1 of ‘void read_foo(std::ifstream&)’ void read_foo (std::ifstream& out);

  


foo.cpp:10:16: error: invalid initialization of reference of type ‘std::ofstream& {aka std::basic_ofstream<char>&}’ from expression of type ‘std::fstream {aka std::basic_fstream<char>}’
write_foo (fs);
^
foo.cpp:4:6: note: in passing argument 1 of ‘void write_foo(std::ofstream&)’ void write_foo (std::ofstream& out);

1 个答案:

答案 0 :(得分:25)

&#34;长篇故事;简短&#34; - 答案

由于std::fstream不是来自std::ofstream,也不来自std::ifstream,因此引用不是与实例&#34;兼容&#34; std::fstream

使用std::istream&std::ostream&,而不是std::ifstream&std::ofstream&(分别)。

void write_data (std::ostream&);
void  read_data (std::istream&);

引言

正如编译器试图告诉你的那样; std::fstream不会从std::ifstream继承,因此您无法使用前者的值初始化对后者的引用。

我偶然发现了一些开发人员,他们似乎认为幕后的std::fstreamstd::ifstreamstd::ofstream之间的某种直接合并,并且它是通过派生而来实现的。

当被问到为什么他们认为是这种情况时,许多人认为答案可以归结为; &#34;因为它有意义,对吧?&#34;


SILLY ANALOGY

想象一下,我们有三个兄弟姐妹; Ivan Owen John ,生活在阅读写作的家庭中就是一切。

所有兄弟出生时都有礼物;

  • 伊万非常擅长阅读,并且一生都给了它,他从不做任何其他事情,而且;
  • Owen 有写作的东西,这是奇怪的,因为他无法阅读,而且;
  • John 很幸运,同时获得阅读写作的技能。

仅仅因为 John 可以做他兄弟所能做的事情,并不意味着他们是他的父母 - 毕竟他们是;他的兄弟们。

所有三兄弟都从其他亲属那里继承了他们的某些特征,而不是彼此。


回答

std::fstream未构建&#34;在&#34;之上std::{i,o}fstream,即使它们共享其各自继承树的某些部分。


  

iostreams inheritance visualized

     

src http://en.cppreference.com/w/cpp/io


在接受通用代码中的流时,您不应该关心&#34; 真实&#34;基础流的类型。

如果我们将 std :: stringstream std :: fstream std :: ofstream 传递给我们,这是否真的重要将一些输出数据写入的函数?不,我们关心的是读/写的能力。

我们通过形成对std::istreamstd::ostreamstd::iostream的引用来表达这一点,当我们需要一个可以的流时,读取分别写两个


注意:如果不明显: Ivan ifstream Owen ofstream John a fstream 。)