我试图在大约20年前首次学习基础知识之后重新学习C ++,然后将其放在一边。那时我开始拿起一本我从中学到的书。这是他的一个例子(我已经发现它有一些过时的语法):
#include <fstream.h>
void main() {
ifstream infile("iocopy.cpp");
if (!infile) cerr << "couldn't open iopcopy.cpp" << endl;
... other junk
}
他对!
上的infile
运算符的解释是它“检查对象是否为非零”,这让我很困惑(对象为零意味着什么? )。所以我决定自己尝试一下:
#include <fstream>
#include <iostream>
void main () {
std::ifstream f ("something");
// if (f == 0) std::cout << "Couldn't open file" << std::endl;
if (!f) std::cout << "Couldn't open file" << std::endl;
}
这可以按预期工作,如果文件不存在则显示消息,如果文件不存在则显示消息。如果我使用(f == 0)
取消注释该行并注释掉以下行,它也可以工作。
我想我在这里找到了!
运算符;我在其中一个头文件中找到了operator!
,以返回fail
字段。我很困惑为什么第一个例子(f == 0)
有效,因为我没有看到任何似乎适用的operator==
。
那是怎么回事?可以将任何类类型的任何变量与0进行比较吗? ifstream
有什么特别之处,那种类型的变量本质上是指针(可以比较为null或0)?或者是否有我错过的operator==
重新定义?我更习惯像Java这样的语言,构造函数不可能返回null值,所以我很困惑。
答案 0 :(得分:4)
<强> C ++ 03 强>
basic_ios
(基类ifstream
)有一个operator void*
,可以隐式转换为void*
。
0
是void*
字面值的有效值,因此您要比较void*
类型的值。
<强> C ++ 11 强>
basic_ios
(基类ifstream
)有explicit operator bool
,只能通过显式转换才能转换为bool
。所以你的例子不应该编译。
bool
可以隐式转换为int
,因此,如果operator bool
不是explicit
,那么您将比较输入int
。
答案 1 :(得分:3)
“检查对象是否为非零”
这不是一个正确的陈述。 basic_ios
类模板(basic_istream
模板从中继承)具有转换运算符,允许在条件下对其进行测试。特别是在C ++ 11之前,它们实现了对void*
的隐式转换,如果流处于无效状态则返回0,否则返回不同的值。那是不对象,但是为此目的生成的人为值。在C ++ 11中,转换是对bool
的显式转换(并且测试f == 0
将失败)