是否可以毫无例外地进行RAII?

Joe*_*Joe 8 c++ raii

如果在构造对象时需要获取的资源可能失败,是否可以进行RAII,如果本地编码标准禁止例外?

如果是这样,在这种情况下处理资源获取失败的规范方式是什么?

Jen*_*ens 7

我一般不会使用无效对象方法,因为我认为这是一个糟糕的设计.构造之后,对象必须处于建立不变量的状态(这是构造函数应该服务的唯一目的).考虑一个strange_vector实现类似的类std::vector,但在调用之后strange_vector<int>(10, 0),该对象将处于不可用状态,因为分配失败.

相反,我会将构造函数声明为private并使用返回可选的工厂方法:

class file
{
public:
    ~file() {fclose(m_file);}

    static std::optional<file> open(std::string const& filename)
    {
        auto f = fopen(filename.c_str(), "r");
        if (f)
        {
            return std::make_optional<file>(f);
        }
        else
        {
            return std::nullopt;
        }
    }

private:
    file(FILE* file);
    FILE* m_file;
};
Run Code Online (Sandbox Code Playgroud)

异常处理的最大好处之一是(除了解耦错误处理和正常的代码路径),你不能意外地忽略它们.如果你想要,你可以创建自己的类optional,当没有用有效对象初始化时,记录错误消息并终止你的程序(或任何其他合理的错误处理).我认为A. Alexandrescu有一个关于系统错误处理的讨论,他实现了一个Expected<T>包含类型值T或异常的类.您可以使用此基础而不是异常添加您的错误处理.

std::optional 它不是标准的一部分,但您可以轻松地将实现作为最近编译器,boost或其他库的一部分.