C++ 为什么我不能在同一代码行中创建和打开ofstream?

C++ 为什么我不能在同一代码行中创建和打开ofstream?,c++,file,oop,fstream,ofstream,C++,File,Oop,Fstream,Ofstream,我可以做到: std::ofstream outfile; outfile.open("foo"); 但不是: std::ofstream outfile.open("foo"); 因为它给出了这个错误: error: expected ';' at end of declaration std::ofstream outfile.open("foo"); ^ 正如您在中看到的 为什么? PS:我知道我只能std::of strea

我可以做到:

std::ofstream outfile; outfile.open("foo");
但不是:

std::ofstream outfile.open("foo");
因为它给出了这个错误:

error: expected ';' at end of declaration
    std::ofstream outfile.open("foo");
                         ^
正如您在中看到的

为什么?

PS:我知道我只能
std::of stream outfile(“foo”),但是我怀疑我缺少C++的机制,这就是为什么我问。
为什么?

因为该语言不允许将声明与成员函数调用相结合。变量
outfile
直到声明之后才存在

使用构造函数打开文件:

std::ofstream outfile("foo");
但不是:

std::ofstream outfile.open("foo");
std::of Stream outfile.open(“foo”)

这是一个简单明了的语法错误。此时,
outfile
被解释为某个未定义对象的名称。编译器根本不理解您想要创建一个类型为
ofstream
的对象

我们可能希望我们可以简单地像这样解决它:

auto outfile = std::ofstream().open("foo"); // call open on a constructed object.
问题是方法
open
不返回流
的副本,因此这不起作用。(它实际上返回void)

将起作用的事情:

// unexciting, but simple - uses a different constructor
std::ofstream outfile{"foo"};
这(IMHO)更具可读性,也更合法:

auto outfile = std::ofstream("foo");
您可以这样做:

std::ofstream outfile { "foo" };

因为语言。C++不允许这样的指令。< /P> 使用构造函数

std::ofstream outpile(“foo”)

或初始化


std::ofstreamoutfile{“foo”}

这类似于当您有一个返回对象的函数,并且希望在同一行中对其调用一个方法时:

struct foo { void bar(){} };
foo create_foo() { return foo(); }
您可以存储
create_foo
的结果,也可以使用其返回值调用方法,但不能同时存储这两个结果:

create_foo().bar();          // OK
auto f = create_foo();       // OK
auto f = create_foo().bar(); // NOPE
回到流的
:您可以编写

std::ofstream().open("foo");

但是您将没有机会获得对流的
的引用

我猜你已经习惯了Java或C#之类的东西,这类东西是可能的:

BufferedReader br = new BufferedReader(new FileReader(FILENAME));
甚至Python:

lines = open("filename").readlines();
这里的诀窍是,用正确的“工厂函数”,你也可以在C++中这样做,但是这不是这个特定的类是如何制作的。上述其他示例,包括以下任一示例:

std::ofstream outfile{"foo"};
auto outfile = std::ofstream("foo");

是C++中的“正常”方式。断开连接的一部分原因是

open()
方法返回void:。因此,当您拥有此代码时:

std::ofstream outfile.open("foo");
它不会编译,因为
open()
是一个成员函数(不是静态的),它返回
void
而不是
std::of stream
,这是您声明要进行的操作

我希望这能帮你解决问题。

因为你不能

真的

C++具有允许的语法,您不应编写不符合该语法的代码

在一个还不存在的对象上使用返回成员函数的
void
,并且没有初始化器的
=
,声明/表达式混合使用的用例是零


但是你已经知道了。

我知道构造函数的事。答案是这样的:“因为语言不允许将声明与成员函数调用相结合。”,最好有一个引用或其他东西。哦,你的编辑很有帮助@gsamaras如果你已经知道构造函数,我们都知道你知道,我不明白你为什么问这个问题。@gsamaras你找不到明确的参考。语言是以一种特殊的方式设计的,如果有动机允许有问题的代码,那么也许会有一种方法来实现它,但我不明白为什么你会需要它。它基本上是在问“为什么我的车没有喷气式发动机,手册上没有说它必须丢失”。同样的道理——这通常是不需要的,而且会使事情变得更加复杂。你可以创造一辆拥有它的汽车(这不是不可能的),但它将是一辆完全不同的汽车,用于完全不同的目的。Rich,我知道!我想知道为什么我尝试的方法不起作用,如果你能把你的答案编辑成那个方向,那就太好了@是的,我明白了。我会考虑我是否能提供更多的见解。这种猜测完全是错误的是的,确实很有帮助。好吧,你赢了一些,你输了一些。但希望它能有所帮助。即使
open()
返回
std::ofstream
,它仍然无效,因为该行是声明和表达式的奇怪混合体,没有引入初始化器。我不太明白GAMARAS,谁知道C++,正试图与这个。@ LightnessRacesinOrbit获得更好的掌握和理解语言,对不起,如果这些问题听起来哑.. @ Lealness CraceSeSeRe纲我知道它将不工作,即使与<代码>()<代码>返回不同,他们需要
autooutfile=std::ofstream::open(“foo.txt”)它不存在。但是,如果这样的工厂这样做了,他们就可以了。我还没有测试,但我猜如果
bar()
返回了一些东西(而不是
void
),那么第三种情况实际上会做些什么。也许不是预期的,但它会起作用。@KevinAnderson是的。如果
bar
将返回对
*this
的引用,甚至可以在同一行中获取引用并调用该方法,但
std::ofstream::open()
的情况并非如此。如果您想知道为什么在对象构造中不允许成员调用,您选择了一个非常糟糕的示例。因为90%的答案是-你可以把名字传给ctor。这个例子选择了我@Slava。。。你是对的,答案部分证明了这一点。@Slava“你可以把名字传给ctor”哦,不,不是真的。。。您不能命名构造函数,也不能在声明或初始化器中直接“调用”它。@LightnessRacesinOrbit我很确定Slava的意思是使用构造函数打开文件,通过将文件名作为构造函数的第一个参数进行传递。@gsamaras您是对的,我指的是文件名。仅供参考,这两个都是使用构造函数初始化的