我创建了一个类,在构造函数中我做了类似的事情:
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");
我怎么知道所有内容都已正确初始化?
答案 0 :(得分: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
块中提供默认值。
答案 1 :(得分:1)
您可以在同一个mannor中检查文件返回的值。如果您使用的是fread
,请检查ferror
。如果您正在进行atoi
转换,请检查atoi
的返回值。那,或者你可以实现异常处理。
要检查文件外部的错误代码,请通过引用传递int指针或int,并将其用作整个构造函数中的控件。当构造函数返回时检查该值。如果在构造函数执行ferror
期间的任何时刻都不为零,那么您的控件应该阻止在构造函数中进一步执行。
答案 2 :(得分: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.
}