假设我们有一个如下所示的类:
class A {
public:
A();
~A();
void foo();
int* pointer;
};
A::A() {
pointer = new int;
}
A::~A() {
delete pointer;
}
A::foo() {
throw "error";
}
以及使用它的以下示例:
Example 1
int main() {
A a;
throw "error";
return 0;
}
Example 2
int main() {
A a;
a.foo();
return 0;
}
在这两种情况下,都会出现内存泄漏,因为由于未处理的异常,A 的析构函数永远不会被调用。
我的问题是,类的用户是否有责任确保通过处理异常来调用析构函数:在第一个示例中,异常与类无关,因此我假设责任在于类的用户,但在第二个示例中,类本身抛出错误 - 是否仍然由类的用户来确保正确处理异常,或者这只是类本身的错误设计?
最佳答案
void throw();
这不会编译。 throw
是保留关键字。
暂时忽略这个细节,您最初的假设并不完全正确。
在这种情况下,异常没有被捕获,程序将终止,因此内存泄漏是学术性的。
但是,如果作用域中有一个 try/catch
block ,它将捕获异常,那么在任何一种情况下都不会出现内存泄漏。在两个示例中,a
对象均已完全构造。因此,抛出的异常将销毁a
,并调用其析构函数。
抛出的异常将展开堆栈,直到捕获异常,并且作为该过程的一部分,销毁本地范围内的所有对象,直到捕获异常。
所以,这是一个有争议的问题。不存在内存泄漏,只要异常最终被捕获,并且没有人需要担心任何事情。
您展示的类大部分符合 RAII
原则(需要一个复制构造函数和一个赋值运算符,以解决 Unresolved 问题)。该类唯一负责的事情是,如果在构造函数中抛出异常,则构造函数分配的任何内容都需要清理。
关于c++ - 类指针成员和异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40710915/