如何将文件流作为类成员 [英] How to have a file stream as a class member

查看:130
本文介绍了如何将文件流作为类成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下在Visual C ++中工作的解析器类

I have the following parser class that works in Visual C++

class Parser
{
   private:
   const char* filename;
   std::ifstream filestream;
   std::vector<std::string> tokens;
   unsigned int linect;

   public:
   Parser(const char* filename);
   bool readline();
   std::string getstrtoken(unsigned int i) const { return tokens[i]; }
   int getinttoken(unsigned int i) const { return atoi(tokens[i].c_str()); }
};

Parser::Parser(const char* filename) :
   filename(filename),
   linect(0)
{
   filestream = ifstream(filename); // OK in VC++, not with GCC?
}

bool Parser::readline()
{
   std::string line;
   getline(filestream, line);
   std::stringstream ss(line);
   std::string token;

   tokens.clear();
   while(getline(ss, token, ' ')){ if(token != "") tokens.push_back(token); }
   linect++;
   return (filestream != NULL);
}

但是当我尝试使用GCC 4.8.2编译它时,我收到错误说我无法分配到 filestream 。从我在本网站的其他地方读到的内容,你可以做到

But when I try to compile it with GCC 4.8.2, I get errors saying that I cannot assign to filestream. From what I read elsewhere on this site, you can do

std::ifstream filestream(filename);

但你做不到

std::ifstream filestream;
filestream = ifstream(filename);

如果我想声明 filestream <我基本上需要做的事情/ code>作为 Parser 类的成员,并在构造函数中初始化它。

which is essentially what I need to do if I want to declare filestream as a member of the Parser class and initialize it in the constructor.

我会喜欢将文件流保存在 Parser 类中,以便使用解析器的人不需要声明并跟踪它。在我看来,这应该是 Parser 类中自包含的内部方法(例如 readline() )是唯一使用它的人。

I would like to have the file stream kept within the Parser class so that those who use the parser don't need to declare and keep track of it. It seems to me that this should be self-contained in the Parser class since its internal methods (e.g. readline()) are the only ones that use it.

有没有办法实现这个适用于两个平台?

Is there a way to achieve this that works with both platforms?

谢谢。

编辑我的解决方法是明确调用 open() ifstream 的方法。我的解析器类构造函数现在看起来像:

edit: My fix was to explicitly call the open() method of ifstream. My parser class constructor now looks like:

Parser::Parser(const char* filename) :
   filename(filename),
   linect(0)
{
   filestream.open(filename);
   // Do some checking to make sure the file exists, etc.
}


推荐答案

您不能,因为 std :: ifstream 已删除了复制构造函数和复制赋值。你可以这样做

You can't, since std::ifstream has deleted copy constructor and copy assignment. You may get around by doing

filestream.swap(ifstream(filename)).

它在visual studio上编译的事实主要是因为它被内联到移动赋值或移动构造函数中(我不太好告诉你究竟是哪一个)。如果您尝试

The fact that it compiles on visual studio is mostly because it gets inlined into either move assignment or move constructor(I'm not so good to tell you which exactly). If you try

std::ifstream myF;
filestream = myF;

它不会编译。

但是你可能会尝试做我写的那个动作,或者你可以调用 .open http://en.cppreference.com/w/cpp/io/basic_ifstream/open

However you may try to do the move I wrote, or you can just call .open(http://en.cppreference.com/w/cpp/io/basic_ifstream/open)

这篇关于如何将文件流作为类成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆