c++ returning refrence to ifstream
Hi All,
Since everyone was so helpful last time i figured i would try you for another question. In java if i want to return an input stream i could just do something like this. Code:
Code:
ifstream& openFile ( char str[] ); Thanks in advance! |
Quote:
What exactly do you think this function gains you? streams use RAII so your code could be written like Code:
int main() |
Quote:
In C++ if you want a function to return an object it allocated, the only direct approach is to return a pointer, not a reference. Then the caller becomes responsible for ultimately deleting the object. In many kinds of programming it is possible and worthwhile to have a much more structured relationship between the creation point of an object and its deletion point. Then it would be a violation of that structure to return a pointer to the function allocated object, so you're not left with good choices. In other kinds of programming, you just recognize that object ownership issues are consistently part of the problem so you must be consistently careful with their solution. I don't know the style nor structure of your project. So one answer is return by pointer and remember to delete later. But that may not be a good answer. |
(example for previous post)
Code:
ifstream* openFile ( char str[] ); Code:
void openFile ( ifstream& inFile, char str[] ); |
A better way to do it is to take a reference to std::ifstream, modify it, and return bool to indicate the result. Returning a new object comparably to the way Java does is often done with std::auto_ptr; however, that's a borderline-useless class because you can't even create a list of std::auto_ptr. If you're actually initializing an object with the return, you can return it by value and initialize with e.g. ifstream inFile( openFile(str) );, which will generally prevent copying the object because inFile in main is constructed where inFile in openFile was at the time openFile returns. These things are what Java hides from you; in reality, Java just creates a pointer to a new object wrapped with a shared pointer. For everything, except maybe integral types. That should generally be avoided in C++, especially when you know what you need at compile time (as is the case here.)
Kevin P. Barry PS This looks like I'm responding to the others here, also; however, it just took me a long time to write my response and by the time I posted it, others had, also. |
I find it hard to believe people are suggesting heap allocation or using a construct in place, when the stream object does not have a copy constructor as it makes no sense. Which copy would own the resource, which one should close it?
|
Quote:
Quote:
Object 1 is in local scope in a function. The function returns that object by value implying temporary object 2 created by copy constructor from object 1. That temporary is the input to the constructor of object 3, so a second call to the copy constructor copying 2 to 3? Sometimes the compiler figures out to short circuit those two copy constructors and do it all with one object. When (if ever) must the compiler short circuit those copy constructors? When (if ever) may the compiler short circuit those copy constructors? If must doesn't equal may, that makes a very confusing features. If they do equal then the examples I've looked at are very confusing and/or compiler bugs. Either way, this is a construct I'd rather not use at all with any object with interesting construction. |
Quote:
Code:
//(compile with '-O0' just to make sure) What if someone wants a list of std::ifstream? Does it make sense to prevent that versatility because "somebody" (not you; the unspecified somebody) doesn't know what to do when something with resources is copied? The answer to the question of resources is as clear here as it is with dynamic memory (at least in the context of POSIX.) Shared memory, threads, mutexes, conditions, etc. are cases where it isn't as clear, but it isn't unreasonable to copy everything within a class except for those things; all one has to do is document the behavior. Kevin Barry PS This is one of the many reasons I always use C for I/O (except in OS-portable libraries.) |
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
|
Quote:
In that example, there is no benefit to having the openFile function at all, vs. opening the file in the main function. If the real code adds something that provides a reason to open the file in that function, then using the heap to allocate the ifstream object and returning it by pointer is the simple way to avoid significantly restructuring the code. |
Quote:
Code:
FILE *rvalue_file = fopen("myfile", "a+"); Kevin Barry Again, if others will use it, all you need to do is document your solutions to ambiguity, e.g. buffering mode, stream position, etc. |
Hi All,
Sorry it has been so long since i was able to check in on this thread. I want to say thanks to everyone for your input. I'm really new to c++ and have some bad habits, or just a few things i got really used to in java that i wont be able to do in c++. Yes, the above post was a "very" slimmed version of what i was trying to do but realised that in c++ i could just pass reference to an already opened ifstream. Example Code:
|
All times are GMT -5. The time now is 12:33 PM. |