首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从ifstream继承

从ifstream继承
EN

Stack Overflow用户
提问于 2011-01-24 17:39:07
回答 3查看 4.5K关注 0票数 4

我可以像这样从ifstream继承并从我的派生类中读取文件吗:

代码语言:javascript
复制
#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;
}

我希望它读取整个文件,但它只读取一个符号(这不是给定文件的第一个符号)……

EN

回答 3

Stack Overflow用户

发布于 2011-01-24 17:49:28

不继承ifstream。如果需要更改输入流的行为,可以继承streambuf,然后围绕它构造一个istream。如果您只想添加辅助对象,请将它们设置为全局的,以便您可以在任何istream上使用它们。

也就是说,您的bug存在于File构造函数中:

代码语言:javascript
复制
File::File(const char *fname, openmode mode)
{
    ifstream(fname, mode);
}

这将构造一个(未命名的) ifstream,然后立即将其关闭。您希望调用超类构造函数:

代码语言:javascript
复制
File::File(const char *fname, openmode mode)
  : ifstream(fname, mode);
{

}
票数 7
EN

Stack Overflow用户

发布于 2011-01-24 17:54:43

我看不出你的提取函数有什么问题,但我不明白从ifstream派生的意义。

从一个类派生的目的是重写它的虚方法,这样当有人将一个istream&或ifstream&传递给一个函数(通常是operator>>)时,您的重写就会被调用。

与STL集合不同,streams确实使用层次结构和v-table,但新手通常会理解错误的概念。

例如,如果您想要更改它使用的缓冲区类型,您可以从basic_streambuf派生并使用一个简单的istream或ostream对象,并附加您的streambuf。

改变打印或读取对象的方式不是通过从iostream或streambuf派生一个新类就能完成的,也不能扩展iomanips,您必须对要流式传输的对象使用包装类。

票数 1
EN

Stack Overflow用户

发布于 2011-01-24 17:47:21

缺少对基构造函数的调用。我想你的意思是:

代码语言:javascript
复制
File::File(const char *fname, openmode mode) : ifstream(fname, mode)
{

}

而不是这样:

代码语言:javascript
复制
File::File(const char *fname, openmode mode)
{
    ifstream(fname, mode);
}

现在,您可能正在读取一些未初始化内存的内容。第二个(当前)代码只是在堆栈上创建一个新的ifstream实例,并立即销毁它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4780503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档