[英]How to clean initialized resources if exception thrown from constructor in c++
前一天我在面试中遇到这个问题。 所以请指导我。
如果在c ++中从构造函数抛出异常,如何清理初始化资源?
诀窍是使用RAII (资源获取是初始化)来管理资源。
如果你有指针成员,那么使用智能指针而不是原始指针,一旦从构造函数抛出异常,它将自动执行清理作业。
使用在销毁资源时释放资源的数据成员(也称为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_error
或bad_alloc
),那么已经初始化的数据成员string1
被销毁,从而释放资源。 就此而言, string2
也被销毁,但如果构造函数抛出,则string2
仍然必须为空,因此没有特别的效果。
string
是管理资源的类的示例,但还有许多其他类。 其中最灵活的被称为“智能指针”,并且可以配置为管理几乎任何资源,而不仅仅是像string
那样自我分配的字符数组。
抛出异常时,堆栈将展开到捕获点。 因此,一切都是在它被建造的地方被毁坏了。
关键是,将每个敏感资源包装到一个类中,析构函数负责处理相关资源。
如果资源是堆分配的对象,则智能指针就是这样(在破坏时删除指向的对象),如果资源是打开的文件,则流在销毁时关闭它。 其他一切都需要自定义包装器。
但请注意,许多“资源”由处理程序表示,它们是无效的*。 这样就可以使用智能poitner,然后使用分配的resoure初始化并指定删除功能。
技术发挥得更好的更多的是品味和机会。
最好的方法是:在构造函数中分配任何资源,并在析构函数中释放任何资源。
C ++中的模板对此非常有用,因为我们可以使对象创建成为原子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.