在构造函数中初始化流

Initializing stream in constructor

本文关键字:初始化 构造函数      更新时间:2023-10-16

我刚刚开始学习C++来自C#背景。

我正在创建一个将解析 CSV 数据的类,我希望使用文件路径或流初始化该类。如果传递了文件路径,则应将_str_in设置为新打开的ifstream

我下面的代码编译,但在第二个构造函数上给出警告"引用成员初始化为临时成员,在构造函数退出后不会保留"。我猜警告与以下内容有关:

  1. 创建ifstream_str_in设置为引用它
  2. 分配给ifstream的内存在构造函数退出后释放
  3. _str_in现在指向未分配的内存,并且可能已损坏。

我已经尝试了不同的方法来实现这一目标并检查了许多 SO 问题,但我被难住了——有什么建议吗?

class TokenParser
{
    std::istream& _str_in;
    char _delim;
public:
    TokenParser::TokenParser(std::istream& str_in, char delim) : _str_in(str_in), _delim(delim)
    {
    }
    TokenParser::TokenParser(std::string& file_path, char delim) : _str_in(std::ifstream(file_path)), _delim(delim)
    {
    }

问题几乎是编译器所描述的:当构造函数完成时,std::ifstream(file_path)创建的对象将消失,因此引用_str_in将立即变得悬而未决。

您可以通过在 TokenParser 中创建一个 std::ifstream 对象并在调用第二个构造函数时使用它来解决此问题:

class TokenParser
{
    std::ifstream _file;
    std::istream& _str_in;
    char _delim;
public:
    TokenParser::TokenParser(std::istream& str_in, char delim) : _str_in(str_in), _delim(delim)
    {
    }
    TokenParser::TokenParser(std::string& file_path, char delim) : _file(file_path), _str_in(_file)), _delim(delim)
    {
    }
...
}

试试这个:
<algorithm>
中使用通用引用std::move

class TokenParser
{
std::istream&& _str_in; // notice the && 'universal reference'
char _delim;
public:
TokenParser::TokenParser(std::istream&& str_in, char delim) 
: _str_in(std::move(str_in)), _delim(delim)
{}
// other ctors...
}