Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheriting from ifstream

Can I inherit from ifstream and read the file from my derived class like this:

#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 whole file, but it reads just one symbol (which is not the first symbol of the given file)...

like image 556
user587271 Avatar asked Feb 25 '23 07:02

user587271


1 Answers

Don't inherit from ifstream. If you need to change an input stream's behavior, inherit from streambuf, then construct an istream around it. If you just want to add helpers, make them global so you can use them on ANY istream.

That said, your bug is in the File constructor:

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

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

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

}
like image 68
bdonlan Avatar answered Mar 03 '23 18:03

bdonlan