问题
class Person {
private:
string firstName;
string lastName;
public:
Person() {}
Person(ifstream &fin) {
fin >> firstName >> lastName;
}
void print() {
cout << firstName
<< " "
<< lastName
<< endl;
}
};
int main() {
vector<Person> v;
ifstream fin("people.txt");
while (true) {
Person p(fin);
if (fin == NULL) { break; }
v.push_back(p);
}
for (size_t i = 0; i < v.size(); i++) {
v[i].print();
}
fin.close();
return 0;
}
Please can you explain me, how following code snippet works? if (fin == NULL) { break; }
fin is a object on stack, not a pointer so it can not become NULL. I was unable to find overloaded operator== function in ifstream class. So I can not understand how this snippet works.
回答1:
The ifstream
class has an operator void *() (or operator bool() in C++11). This is what is called when you test (fin == NULL)
.
Testing fin == NULL
should be exactly the same as testing fin.fail()
.
回答2:
The base classes of istream
and ostream
have implicit conversion
functions, which allow them to be used as a boolean value; in pre-C++11,
the implicit conversion was to void*
.
It was never the intent that the result of this conversion be used as a
pointer, and code like fin == NULL
shows an extremely poor
understanding of C++ and the standard streams. The idiomatic way of
writing the first loop would be to define a default constructor and an
operator>>
for Person
, and then write:
Person p;
while ( fin >> p ) {
v.push_back( p );
}
(And while I'm at it: you really should test the return value of
fin.close()
, and not return 0
if it fails:
fin.close();
return fin ? EXIT_SUCCESS : EXIT_FAILURE;
.)
回答3:
This isn’t how streams are supposed to be used. True, this (unfortunately!) compiles and even does the “right” thing. But don’t write code like this. Whoever wrote this code probably thought they were clever.
But what they really did was break the expectations of C++ programmers by introducing a new, unconventional API, with no real advantages.
This code initialises an object of type Person
from an input stream. Unfortunately, by doing this, the code forgoes the opportunity to test for errors while reading the object. This isn’t good. An object should not have a constructor accepting an input stream, it should overload operator>>
.
来源:https://stackoverflow.com/questions/10680698/c-reading-a-file-using-ifstream