测试istream对象

testing an istream object

本文关键字:对象 istream 测试      更新时间:2023-10-16

当我在测试中使用std::istream对象(在下面的例子中来自cplusplus.com,一个std::ifstream): "if (myistreamobject)"时,在堆栈中自动分配的对象永远不会为空,对吧?在下面的示例中,我们使用相同的测试来检查是否从文件中读取了所有字节…这真是一个奇怪的代码,我通常在处理指针时使用这种风格…

我想知道std::istream在测试中使用的是哪种机制来返回值,以及这个值的真正含义…(最后一个操作的成功/失败??)它是bool类型转换的重载(如MFC类CString中的const char*操作符)还是另一种技术?

因为对象从来不是空的,所以把它放在测试中总是返回true。

// read a file into memory
#include <iostream>     // std::cout
#include <fstream>      // std::ifstream
int main () {
  std::ifstream is ("test.txt", std::ifstream::binary);
  if (is) {
    // get length of file:
    is.seekg (0, is.end);
    int length = is.tellg();
    is.seekg (0, is.beg);
    char * buffer = new char [length];
    std::cout << "Reading " << length << " characters... ";
    // read data as a block:
    is.read (buffer,length);
    if (is) // <== this is really odd
      std::cout << "all characters read successfully.";
    else
      std::cout << "error: only " << is.gcount() << " could be read";
    is.close();
    // ...buffer contains the entire file...
    delete[] buffer;
  }
  return 0;
}
if (expression)

测试expression的值是否为布尔值true。它适用于指针,因为nullptr/NULL/0的值为false,其他所有值为true。出于同样的原因,它也适用于整数值。

对于一个对象,它属于operator bool(),参见http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool。

检查流是否没有错误。

1)如果fail()返回true则返回空指针,否则返回非空指针。该指针可隐式转换为bool类型,并可在布尔类型上下文中使用。

2)如果流没有错误并且准备好进行I/O操作,则返回true。具体来说,返回!fail()。

该操作符可以使用流和返回对流的引用的函数作为循环条件,从而产生习惯的c++输入循环,如while(stream>> value){…}或while(getline(stream, string)){…}.

这样的循环只有在输入操作成功时才执行循环体。

operator bool() 
如果流没有错误,

返回true,否则返回false。

"no error"的概念与之前对流本身所做的操作有关。

例如:在调用构造函数

之后
std::ifstream is ("test.txt", std::ifstream::binary);

设置流对象的内部状态标志。因此,当调用操作符bool时,要检查构造操作是否失败。

方法

is.read(...)

也设置了这个内部状态标志,正如你在参考中看到的:

通过修改内部状态标志来发出错误信号:eofbitfailbitbadbit

因此,在方法调用之后,如果流到达EOF(文件结束),则设置状态位,操作符bool将返回一个正值。

这意味着在这种情况下当你用

测试流时
if (is) { ... }

,设置状态位,则验证条件,取if支路

std::istream的操作符声明如下:explicit operator bool() const;

当你写if(SomeStdIstremObject) { ... }调用if(SomeStdIstreamObject.operator bool())时没有检查非零