3

我创建了一个类,并在构造函数中执行以下操作:

MyClass(string file)
{
    ifstream str;
    str.open (file, ifstream::in);

    // initialize class variables based on values from file

    str.close();
}

我怎么知道在读取文件时是否出现错误并且值未正确初始化?上述方法是错误的吗?如果我想从构造函数中的文件初始化我的变量,我还能怎么做?

编辑,澄清:我要问的是这样的声明:

MyClass myclass("path/to/my/file.txt");

我怎么知道一切都已正确初始化?

4

3 回答 3

3

一种可能性是使用异常:

...
ifstream str;
str.exceptions(std::ifstream::failbit);
// continue as before

然后,如果你的构造函数抛出一个异常,你就知道有些东西不起作用。

另一种可能性是检测构造函数中的故障并设置一个可以由调用代码检查的状态变量。

以下是两种解决方案:

#include <iostream>
#include <exception>
#include <string>
#include <fstream>

struct MyClass1 {
  int i;
  MyClass1(const char * iniFile) {
    std::ifstream in;
    in.exceptions(std::ifstream::failbit);
    in.open(iniFile);
    in >> i;
  }
};

struct MyClass2 {
  int i;
  bool isValid;
  MyClass2(const char * iniFile) {
    try {
      std::ifstream in;
      in.exceptions(std::ifstream::failbit);
      in.open(iniFile);
      in >> i;
      isValid = true;
    } catch(std::ios_base::failure &fail) {
      isValid = false;
    }
  }
};

int main () {
  try {
    MyClass1 mc1("somefile.txt");
  } catch(std::exception& fail) {
    std::cout << "oops 1\n";
  }

  MyClass2 mc2("somefile.txt");
  if(!mc2.isValid) {
    std::cout << "oops 2\n";
  }
}

假设somefile.txt不存在,那应该打印两行“oops”。

最后,第三种可能性是确保构造函数永远不会失败catch在您的情况下,您可以在块中提供默认值。

于 2012-11-29T22:20:57.240 回答
1

您将以与往常相同的方式检查文件返回的值。如果您正在使用fread,请检查ferror. 如果您正在进行atoi转换,请检查atoi. 那,或者您可以实现异常处理。

要检查文件外部的错误代码,请通过引用传递一个 int 指针或一个 int 并将其用作整个构造函数的控件。当构造函数返回时检查该值。如果在构造函数执行期间的任何时候ferror不为零,则您的控件应防止在构造函数中进一步执行。

于 2012-11-29T22:22:18.143 回答
1

就个人而言,我会使用 Rob 已经回答的异常。

另一种选择是传递对成功标志的引用。

MyClass(std::string filename, bool& success)
{
  success = true;
  if(!str.open(filename))
  {
    success = false;
  }      
}

像这样检查成功。

bool success;
MyClass("filename", success);
if(!success)
{
  // Something failed during the class instantiation.
}
于 2012-11-29T22:25:56.727 回答