Search code examples
c++pointersfstreamcinistream

Pointer to an fstream issue with >> operator?


I'm trying to use file streams to read input and I need to be able to maintain a pointer to a file when I transfer it in between classes. Here is a rough outline of what I'm trying to do:

class A {
friend class B;
public:
    void somefunction();

private:
    fstream o;
    B b;
};

class B {
   fstream * in;

   public:
        void input();
        void modify(fstream *);
};

Here is a simple representation of the two classes I'm trying to work with. I have a function that modifies the fstream like so:

void A::somefunction() {
    B.modify(o);
}

void B::modify(fstream * o) {
     this -> in = o;
}

Here I pass the other fstream so that the class B now maintains a pointer to that file. However, when I try to read input using it, I fail:

void B::input() {
    while (*in >> object) {
        cout << object << endl;
    }
}

The statement simply evaluates to false and the while loop does not execute. I'm wondering if it is an issue with the streams, but I'm not sure. Does anyone have any suggestions?

EDIT:

B b;
b.modify(o);

I want to pass in the fstream o from class A into class B. I set the fstream * in in class A to the fstream o in class B. I forgot to add that fstream o is reading from a file, and I would like to essentially "transfer" the stream to class B so that it may read from the file.


Solution

  • First of all, streams are not copyable (their copy constructor is private in pre-C++11 and deleted in C++11 and C++14). If you have a member of type fstream, you need to std::move into it (using C++11 or later). If you don't want to use (cannot use) C++11, then you need to pass pointers (or references) around. Here is one way of doing it with pointers:

    #include <iostream>
    #include <fstream>
    
    class A
    {
        std::fstream* o; // pointer to fstream, not fstream
    public:
        A(std::fstream* o): o(o) {}
        std::fstream* get_fstream() const
        {
            return o;
        }
    };
    
    class B
    {
        std::fstream* in;
    public:
        void modify(std::fstream* o)
        {
            this -> in = o;
        }
        void input()
        {
            std::string object;
            while (*in >> object) {
                std::cout << object << std::endl;
            }
        }
    };
    
    int main()
    {
        std::fstream* ifile = new std::fstream("test.txt");
        A a(ifile);
        B b;
        b.modify(a.get_fstream());
        b.input();
        delete ifile;
    }
    

    I prefer pointers vs references since a reference must be initialized and cannot be changed later.