移动赋值操作是否会关闭原始的std::fstream流?

10

自从c++11以来,我们可以将一个std::fstream对象移动分配给另一个对象,但我无法找到说明,如果fstream对象已经与文件关联(is_open()==true),会发生什么。

因此,我的问题是,在下面的代码中,File1.txt是否会被正确关闭,如果需要手动关闭它,如果我不关闭它会发生什么?

std::fstream file("File1.txt");   
file = std::fstream("File2.txt"); //will this implicitly call file.close()?             

1
呃……file = std::fstream("File2.txt"); - erip
@erip:我找不到错别字,你在暗示什么? - MikeMB
只是看起来不太好看。 - erip
@erip:是的,这当然是一个人为制造的例子。实际用例是首先使用临时的std::fstream变量打开文件,只有在成功打开后才将其移动分配给原始变量。 - MikeMB
2个回答

8
fstream对象的移动赋值将导致其关联的filebuf的移动赋值。文档已经很清楚地表明旧文件首先关闭(就像file.rdbuf()->close()而不是file.close()):

basic_filebuf& operator=(basic_filebuf&& rhs);

  1. 效果:调用this->close(),然后从rhs中移动分配。移动赋值后,*this具有它从rhs移动构造时所具有的可观察状态。
  2. 返回:*this

basic_fstream& operator=(basic_fstream&& rhs);

  1. 效果:从rhs的基础和成员中移动分配*this的基础和相应成员。
  2. 返回:*this
(这是草案n4527的措辞,至少自草案n3485以来未发生变化)

你知道吗,这在早期版本(特别是C++11版本)的标准中是否已经说明了吗? - MikeMB
@MikeMB:n3485似乎有完全相同的措辞。 - Ben Voigt
该死,阅读标准真的不是我的强项。谢谢。 - MikeMB

4

由于实际的文件相关机制被“隐藏”在相应的缓冲区中(流主要提供格式化IO),因此您应该查看 std::basic_filebuf 文档:

首先调用close()来关闭关联的文件,然后将 rhs 的内容移动到 * this 中:放置和获取缓冲区,关联文件、区域设置,打开模式,is_open 标志和任何其他状态。移动后,rhs 不再与文件关联,而且 rhs.is_open () == false。

摘自http://en.cppreference.com/w/cpp/io/basic_filebuf/operator%3D


是的,但这只涉及到右手边 - 它并没有说明左手边的状态会发生什么。 - MikeMB
@MikeMB,"包括缓冲区、关联文件、区域设置、打开模式和is_open变量"这些对你来说还不够吗? - SergeyA
@SergeyA:你的回答完全避免了谈论移动缓冲区对被替换缓冲区的影响。 - Ben Voigt
如果我有一个带原始指针的类,并且我只是从rhs复制所有内容,那并不意味着我正在删除该指针指向的内容。 - MikeMB
@BenVoigt,我的错。我把问题看成是关于构造函数而不是赋值运算符。已编辑。 - SergeyA

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