How do I open a file in one routine and close it in a separate routine or is this forbidden?

Unfortunately I have many years of experience with structural programming and the lessons I have learned over the years do not translate well to object oriented programming. Purely as an exercise I want to write a routine within a class that opens and closes a file, which is simple to do. An example is posted below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "Open_Close_File.h"

void Open_Close_File::Open_File()
{
    std::ifstream inp("Test.txt",std::ios::in | std::ios::binary);
    if(!inp) {
        std::cout << "Cannot Open Test.txt\n";
    }
    inp.close();
}
[code]

This code works quite well.  However, for the sake of argument lets assume that I want to close the file in a different routine than I opened it in....how do I do this in C++.  The code attached to this one is my attempt at it, but it does not recognize the inp as a keyword that defines the file and instead I think it is looking at "inp" as the data stream from the file, but I am not sure.

[code]
#include "Open_Close_File.h"

void Open_Close_File::Open_File()
{
    std::ifstream inp("Test.txt",std::ios::in | std::ios::binary);
    if(!inp) {
        std::cout << "Cannot Open Test.txt\n";
    }
    Close_File(inp);
}

void Open_Close_File::Close_File(std::istream& inp)
{
    inp.close();
}
Why close the stream at all? When the function returns to the calling function the file will be closed by the class destructor when the stream goes out of scope because the stream is local to the function.
Last edited on
closed account (48T7M4Gy)
@ jowebb123

Aside from what jlb says, which is perfectly correct, the idea you have in mind to close the file via a function passing the stream parameter is OK even if it is just as an exercise.

Don't forget you can always test whether you get it right by an extra line or two to react to whether it is open (or closed). That's another exercise in itself.
Aha, this is an instance of not realizing what I already know. You are right, the destructor will close it on my behalf. I like to have lines of code to do that, because I think it makes the code look much more organized for the person who has to read the code, but you are right. Thank you for pointing that out
C++ iostreams were not designed to be copyable. (And attempts to make them movable showed that to be a bad idea.)

You can, however create them on the heap:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <fstream>
#include <iostream>
#include <string>
using namespace std;

istream* open()
{
  ifstream* f = new ifstream( "a.cpp" );
  return f;
}

void close( istream* f )
{
  dynamic_cast <ifstream*> ( f )->close();
}

int main()
{
  istream* i = open();

  string s;
  while (getline( *i, s )) cout << s << "\n";

  close( i );
}

However, it should be noted that there is really never any need to do this... And it is free to pass references to file streams around.

If you are concerned about making file types come from a different type of source, you can encapsulate that kind of behavior.

But you typically just need to know what kind of file you are going to open, and open it in one spot and close it when you are done.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void quux( istream& f )
{
   ...
}

int main()
{
  ifstream f( ... );
  quux( f );

  quux( cin );

  istringstream s( ... );
  quux( s );

Hope this helps.
closed account (48T7M4Gy)
As we all know using '&' to pass by reference in a function/call arrangement does not create a copy. The close() function does not serve the purpose of a stream destructor either.


Closing a file
When we are finished with our input and output operations on a file we shall close it so that the operating system is notified and its resources become available again. For that, we call the stream's member function close. This member function takes flushes the associated buffers and closes the file:


myfile.close();


Once this member function is called, the stream object can be re-used to open another file, and the file is available again to be opened by other processes.

In case that an object is destroyed while still associated with an open file, the destructor automatically calls the member function close.
Topic archived. No new replies allowed.