2

在大约 20 年前第一次学习了基础知识但随后将其搁置一旁后,我正试图重新开始学习 C++。我从拿起一本我从那时学到的书开始。这是他的一个例子(我已经发现它有一些过时的语法):

#include <fstream.h>
void main() {
    ifstream infile("iocopy.cpp");
    if (!infile) cerr << "couldn't open iopcopy.cpp" << endl;
    ... other junk
}

他对!运算符 on的解释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 这样的语言,构造函数不可能返回空值,所以我很困惑。

4

2 回答 2

5

C++03

basic_ios( 的基类ifstream) 具有operator void*使其隐式转换为 的void*

0是文字的有效值void*,因此您正在比较 type 的值void*

C++11

basic_ios( 的基类ifstream) 有一个explicit operator bool使得它bool只能通过显式转换转换为。所以你的例子不应该编译。

boolint根据 C++ 语言类型转换规则,可以隐式转换为,因此如果operator bool不是explicit,那么您将比较 type 的值int

于 2013-09-04T16:55:18.843 回答
3

“检查对象是否非零”

这不是一个正确的说法。类basic_ios模板(basic_istream模板继承自)有一个转换运算符,允许在条件下对其进行测试。特别是,在 C++11 之前,它们实现了隐式转换void*,如果流处于无效状态,则返回 0,否则返回不同的值。那不是对象,而是为此目的而产生的人为价值。在 C++11 中,转换是显式转换bool(并且测试f == 0将失败)

于 2013-09-04T16:55:17.063 回答