is_open() returns true if a previous call to open() succeeded and there has been no intervening call to close(). In your example, open() is called from the constructor.
fail() returns true if failbit or badbit is set in rdstate.
failbit generally means that a conversion failed. For example, you tried to read an integer, but the next character is a letter. The stream is ok; you could read a character next and it would succeed. You would not expect the failbit to be set right after opening a file.
badbit is set when the stream is corrupt and the next operation will fail.