4

当我运行代码时

istream s;
if (s)
  // ...

我可以测试 istream(或任何 ios 对象)的真值。据我了解,这是因为 ios 定义operator!函数的方式。(供参考,http://www.cplusplus.com/reference/ios/ios/operatornot/。)我的问题是:为什么s像上面那样放入 if 语句会导致operator!函数被评估?作为第二个问题,如果我将任何对象放在 if 语句中,C++ 将使用哪些可能的方式来评估其真实性?

4

3 回答 3

5

在 C++03 中,此检查是通过operator void*成员函数完成的,如果流处于良好状态,则返回非空指针,否则返回 NULL。由于空指针评估为假,非空指针评估为真,因此此检查工作正常。

但是,它确实存在问题,因为您可以这样做:

std::cout << std::cout;

这将调用operator void*函数并打印出 0 或 的地址cout,具体取决于流是否良好。这不是一件好事,因为上面的代码似乎没有这样做。更糟糕的是,你可以做

delete std::cout;

如果流不好,这会导致未定义的行为。

在 C++11 中,这已更改,因此流具有一个explicit operator bool成员函数,它允许将流显式转换为布尔值。这消除了上述问题,并且是支持 if 检查对象的首选方式。

希望这可以帮助!

于 2013-01-27T18:47:52.133 回答
2

模板basic_ios有一个explicit operator bool在这种情况下被调用的。在过去是这样operator void*,但这是有争议的,因为有些人担心有一天有人会写作delete my_stream

于 2013-01-27T18:46:33.883 回答
0

std::istream有一个operator bool()在 if 语句中调用的重载。operator!也是一个成员函数,它检查流中是否发生错误,但在这种情况下不在 if 语句中使用。

于 2013-01-27T18:46:43.437 回答