假设我们有类如下的类:
class A {
public:
A();
~A();
void foo();
int* pointer;
};
A::A() {
pointer = new int;
}
A::~A() {
delete pointer;
}
A::foo() {
throw "error";
}
以下使用它的例子:
示例1
int main() {
A a;
throw "error";
return 0;
}
示例2
int main() {
A a;
a.foo();
return 0;
}
在这两种情况下,都会发生内存泄漏,因为由于未处理的异常,永远不会调用A的析构函数。
我的问题是,类的用户是否有责任确保通过处理异常来调用析构函数:在第一个示例中,异常与类无关,所以我认为责任在于该类的用户,但在第二个例子中,类本身正在抛出错误 - 是否仍然取决于类的用户以确保正确处理异常,或者这只是类本身的糟糕设计?
答案 0 :(得分:3)
void throw();
这不会编译。 throw
是保留的关键字。
暂时忽略这个细节,你的初步假设并不完全正确。
在这种情况下,不会捕获异常并且程序将终止,因此内存泄漏是学术性的。
但是,如果范围中有try/catch
块,那将捕获异常,在任何一种情况下都不会发生内存泄漏。在两个示例中,a
对象已完全构造。因此,抛出的异常将破坏a
,并调用其析构函数。
抛出异常将展开堆栈直到捕获到异常,并且作为该进程的一部分,销毁本地范围内的所有对象,直到捕获到异常。
所以,这是一个有争议的问题。没有内存泄漏,前提是异常最终被捕获,没有人需要担心任何事情。
您展示的类大多符合RAII
原则(需要复制构造函数和赋值运算符,以包装松散的末尾)。该类唯一负责的是,如果在构造函数 中抛出 ,则无论构造函数分配了什么都需要清理。
答案 1 :(得分:1)
这非常无关紧要。存在“内存泄漏”的唯一原因是程序将结束,这通常会清理内存。
在任何情况下,如果程序由于未处理的异常而退出,那么这不是类的问题。想象一下,如果你有100个类,所有这些类都需要关心一个函数(main
)是否无法处理异常。