我想借助 RAII 实现一个类。应该在构造函数中获取资源,但有可能获取失败。我将在下面使用 FILE 给出一个例子:
class file {
public:
file(const char* filename) {
file_ = fopen(filename, "w+");
if(!file_) {
// Okay
}
else {
// ERROR
}
}
~file() {
if (fclose(file_)) {
// ERROR
}
}
void write(const char* str) {
if (EOF == fputs(str, file_)) {
throw runtime_error("file write failure");
}
}
private:
FILE* file_;
};
那么,处理 fopen 返回 NULL 时发生的错误的最佳方法是什么?因为它是构造函数,所以我不能返回 NULL。
我希望有人能给我提示如何处理此类错误!
谢谢你,最好的问候,
闪光器
最佳答案
构造函数报告失败的唯一方法是抛出异常。
相反,析构函数不得抛出异常(如果析构函数在堆栈展开期间抛出异常,则调用 std::terminate
,这将默认结束程序)。
如果销毁失败,可以
- 默默地接受错误
- 中止程序
- 记录错误并执行上述任一操作。
如果您正确使用 RAII,异常可以无损地遍历您的代码。
这里的例子:
#include <cerrno>
#include <cstring>
#include <sstream>
file::file(const char* filename)
{
file_ = fopen(filename, "w+");
if (!file_)
{
std::ostringstream os;
os << "Cannot open " << filename << ": "
<< std::strerror(errno);
throw std::runtime_error(os.str());
}
}
file::~file()
{
fclose(file_);
}
请注意,这段代码有很多错误:fclose
函数可能会失败,失败可能与关闭有关,也可能无关(例如,某些写入错误仅在刷新时报告 close
POSIX 系统上的系统调用)。请将 iostreams 用于 C++ 中的文件 I/O,因为它们为这些问题提供了方便的抽象。
关于c++ - 如果资源获取可能失败,如何实现 RAII,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8565463/