简体   繁体   中英

C++, reading a file using ifstream

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.

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() .

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;

.)

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>> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM