【问题标题】:Class member initializer to initialize ifstream with error check?使用错误检查初始化 ifstream 的类成员初始化程序?
【发布时间】:2017-02-12 23:10:03
【问题描述】:

我正在尝试使用类成员初始化程序的 C++11 特性来初始化类的变量。我拥有的类变量是 std::string 和 std::ifstream。

class A{
    std::string filename = "f1.txt";
    std::ifstream filestream = ....
public:
    ....
};

有什么方法可以初始化文件流并同时使用类成员初始化检查错误。

我想做的是,类似于以下内容:

class A{
    std::string filename = "f1.txt";
    std::ifstream filestream(filename);
    if(filestream.is_open()) .... // check if file cannot be opened
public:
    ....
};

【问题讨论】:

  • 嗯,不。如果文件无法打开,你想做什么?您可以在构造函数中检查它,并可能引发异常?但我认为这是不好的做法。
  • @Rakete1111 这也是我的想法.. 我只是想确定我是否做对了.. 所以你建议我在构造函数中进行 ifstream 初始化?
  • 是的,但我自己也不知道:/对不起。
  • 这是一种不好的做法。正如 Rakete1111 所说,从构造函数中检查并初始化成员变量。

标签: c++ c++11


【解决方案1】:

您可以编写和调用执行适当检查的内联 lambda 表达式;这样的 lambda 表达式可以访问数据成员:

class A {
    std::string filename = "f1.txt";
    std::ifstream filestream = [&] {
        std::ifstream fs{filename};
        if (!fs)
            throw std::runtime_error("failed to open ifstream");
        return fs;
    }();
};

将逻辑分离成一个以filename为参数的可重用辅助函数可能更清楚,例如静态成员函数:

class A {
    std::string filename = "f1.txt";
    std::ifstream filestream = openChecked(filename);
    static std::ifstream openChecked(std::string const& filename)
    {
        std::ifstream fs{filename};
        if (!fs)
            throw std::runtime_error("failed to open ifstream");
        return fs;
    }
};

【讨论】:

  • 我在您回答后对此进行了进一步的思考,并愿意接受您的回答。看到您的答案后,我的想法是,如果用户选择使用不同的文件名怎么办?在这种情况下,我可能不得不使用覆盖类成员初始化文件名​​的 mem-init 构造函数。
  • @solti 是的,这绝对是覆盖默认文件名的正确方法。
猜你喜欢
  • 2015-03-22
  • 2019-09-10
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 1970-01-01
相关资源
最近更新 更多