问题描述
#include <iostream>
#include <fstream>
class A {
private:
std::ostream&& out;
public:
A(std::ostream&& o) : out(std::move(o)) {
out.write("test",4);
}
void writeTest2() {
out.write("test2",5);
out.flush(); // still does nothing.
}
};
int main() {
A a{std::ofstream{"testic"}};
a.writeTest2();
}
运行上述代码时,将按预期方式创建名为testic
的文件。但是,创建的文件包含test
但不包含testtest2
,这显然是意外的。究竟是什么导致了此行为?
将std::ostream
用作左值引用时,它可以按预期运行。
其他信息
- 编译器尝试:
clang
,gcc
。 - 在平台上: Linux(4.19.0-11-amd64)。
解决方法
您创建的临时std::ofstream{"testic"}
仅在构造函数调用期间存在。之后,它将销毁并关闭文件,这意味着您将获得一个引用垃圾的引用。使用该引用会导致未定义的行为。
要修复此问题,您可以一起删除所有引用({{1}和 &&
中的std::ostream&& out
),并让它创建一个从临时对象初始化的新对象。
由于std::ostream&& o
无法移动,因此上述操作无效。如果要保持多态性,则必须使用指针。如果那并不重要,则可以将所有std::ostream
更改为std::ostream&&
:
std::ofstream