繁体   English   中英

如果在c ++中从构造函数抛出异常,如何清理初始化资源

[英]How to clean initialized resources if exception thrown from constructor in c++

前一天我在面试中遇到这个问题。 所以请指导我。

如果在c ++中从构造函数抛出异常,如何清理初始化资源?

诀窍是使用RAII (资源获取是初始化)来管理资源。

如果你有指针成员,那么使用智能指针而不是原始指针,一旦从构造函数抛出异常,它将自动执行清理作业。

好读:
Herb Sutter出色的GotW文章“建筑失败”

使用在销毁资源时释放资源的数据成员(也称为RAII)。

例如:

struct TwoStrings {
    std::string string1;
    std::string string2;
    TwoStrings(const std::string &input) : string1(input) {
        if (!input[1] == ':') {
            throw std::logic_error('not a Windows absolute path');
            // yes, absolute paths can begin \\, this is a toy example
        }
        if (input.back() == '\\') {
            string2 = input;
        } else {
            string2 = input + "\\";
        }
    }
};

如果构造函数抛出( logic_errorbad_alloc ),那么已经初始化的数据成员string1被销毁,从而释放资源。 就此而言, string2也被销毁,但如果构造函数抛出,则string2仍然必须为空,因此没有特别的效果。

string是管理资源的类的示例,但还有许多其他类。 其中最灵活的被称为“智能指针”,并且可以配置为管理几乎任何资源,而不仅仅是像string那样自我分配的字符数组。

抛出异常时,堆栈将展开到捕获点。 因此,一切都是在它被建造的地方被毁坏了。

关键是,将每个敏感资源包装到一个类中,析构函数负责处理相关资源。

如果资源是堆分配的对象,则智能指针就是这样(在破坏时删除指向的对象),如果资源是打开的文件,则流在销毁时关闭它。 其他一切都需要自定义包装器。

但请注意,许多“资源”由处理程序表示,它们是无效的*。 这样就可以使用智能poitner,然后使用分配的resoure初始化并指定删除功能。

技术发挥得更好的更多的是品味和机会。

最好的方法是:在构造函数中分配任何资源,并在析构函数中释放任何资源。

C ++中的模板对此非常有用,因为我们可以使对象创建成为原子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM