0

I have a class that accepts an istream reference in the constructor. If the constructor is passed a temporary object like myclass obj(ifstream("filename")); will that ifstream be good for the life of obj? Does it depend on whether or not it is assigned to a reference or pointer in the class?

For example:

class test
{
public:
    istream *p;
    test(istream &is)
    {
        p = &is;
        cout << "a constructor" << endl;
    }
    ~test()
    {
        cout << "a destructor" << endl;
    }
    bool isgood()
    {
        return p->good();
    }
};

int main()
{
    test test(ifstream("test.cpp"));
    cout << test.isgood() << endl;
}

Output:

a constructor
1
a destructor

Just because the output says the file is good I don't know if it's been destroyed or what. If there is a part of the standard that covers this please let me know. Thanks

loop
  • 3,460
  • 5
  • 34
  • 57
  • 3
    That code shouldn't even compile... – David G Feb 26 '14 at 22:42
  • 1
    the ifstream will close at the end of the block and be invalid after that. `p` will point to garbage – JoshG79 Feb 26 '14 at 22:43
  • I'm using Visual Studio 2010. @Josh the end of which block? I'm trying to figure out if the fstream that's opened in the constructor is valid until the end of main(). Thanks – loop Feb 26 '14 at 22:45
  • 2
    It is hard to answer the question, because your code uses a non-standard "extension" to the language. So you have to look it up in your compiler's documentation. – juanchopanza Feb 26 '14 at 22:47
  • @juanchopanza I don't know what the nonstandard extension is and I would like to write portable code so please tell me what I should change. – loop Feb 26 '14 at 22:48
  • Initialize the `ifstream` in `main` before `test`, and pass a reference to the `test` constructor. – juanchopanza Feb 26 '14 at 22:51
  • Temporary objects aren't standard? – loop Feb 26 '14 at 22:54
  • Temporary objects are standard, but binding a non-`const` lvalue reference function parameter (like `istream& is`) to one is not. – aschepler Feb 26 '14 at 22:58
  • Oh boy. Is there a good resource that explains the difference in depth? I'm programming in Visual Studio and I thought it was normal to do that. – loop Feb 26 '14 at 22:59
  • possible duplicate of [Why lifetime of temporary doesn't extend till lifetime of enclosing object?](http://stackoverflow.com/questions/6936720/why-lifetime-of-temporary-doesnt-extend-till-lifetime-of-enclosing-object) – fredoverflow Feb 27 '14 at 09:04
  • @Fred Thanks for the link that's a pretty good discussion – loop Feb 27 '14 at 23:09

1 Answers1

2

Sorry, I don't have enough reputation to comment.

The temporary istream is good only in the constructor. Even though you use the address of the istream to set the value of the pointer, you can no longer use it once the constructor has returned. Since after the constructor call, the temporary ifstream has already been closed and destructed. So the pointer will be pointing to garbage as @Josh mentioned. You may modify your code to pass the filename into the constructor and use the filename to initialize an member ifstream (not a pointer to ifstream). Then you can use the stream through the lifespan of the object.

james
  • 242
  • 2
  • 8