Ifstream inheritance

Can I inherit from ifstream and read the file from my derived class as follows:

#include <iostream>

using namespace std;

const string usage_str = "Usage: extract <file>";

class File: public ifstream
{
public:
    explicit File(const char *fname, openmode mode = in);
    void extract(ostream& o);
};

File::File(const char *fname, openmode mode)
{
    ifstream(fname, mode);
}

void File::extract(ostream& o)
{
    char ch;
    char buf[512];
    int i = 0;

    while (good()) {
        getline(buf, sizeof(buf));
        o<<buf;
        i++;
    }   
    cout<<"Done "<<i<<" times"<<endl;
}

void msg_exit(ostream& o, const string& msg, int exit_code)
{
    o<<msg<<endl;
    exit(exit_code);
}

int do_extract(int argc, char *argv[])
{
    cout<<"Opening "<<argv[1]<<endl;
    File f(argv[1]);
    if (! f)
        msg_exit(cerr, usage_str, 1);
    f.extract(cout);
    return 0;
}

int main(int argc, char *argv[])
{
    if (argc < 2)
        msg_exit(cout, usage_str, 0);

    do_extract(argc, argv);
    return 0;
}

I expect it to read the entire file, but it only reads one character (which is not the first character of this file) ...

+3
source share
3 answers

Do not inherit from ifstream. If you need to change the behavior of the input stream, inherit from streambuf , then create istreamaround it. If you just want to add helpers, make them global so you can use them on ANY istream.

However, your error is in the file constructor:

File::File(const char *fname, openmode mode)
{
    ifstream(fname, mode);
}

This creates an (unnamed) ifstream, and then closes it immediately. You want to call the constructor of the superclass:

File::File(const char *fname, openmode mode)
  : ifstream(fname, mode);
{

}
+6

extract, , ifstream.

, , - istream & ifstream & ( → ), .

STL, v-, .

, , , basic_streambuf istream ostream streambuf.

-, , iostream streambuf, iomanips, - , .

+1

You are missing the call to the base constructor. I think you mean this:

File::File(const char *fname, openmode mode) : ifstream(fname, mode)
{

}

instead of this:

File::File(const char *fname, openmode mode)
{
    ifstream(fname, mode);
}

Now you are probably reading the contents of some uninitialized memory. The second (current) code simply creates a new ifstream instance on the stack and immediately destroys it.

0
source

Source: https://habr.com/ru/post/1787407/


All Articles