类指针成员和异常处理

时间:2016-11-21 00:01:08

标签: c++ pointers memory-management memory-leaks exception-handling

假设我们有类如下的类:

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的析构函数。

我的问题是,类的用户是否有责任确保通过处理异常来调用析构函数:在第一个示例中,异常与类无关,所以我认为责任在于该类的用户,但在第二个例子中,类本身正在抛出错误 - 是否仍然取决于类的用户以确保正确处理异常,或者这只是类本身的糟糕设计?

2 个答案:

答案 0 :(得分:3)

void throw();

这不会编译。 throw是保留的关键字。

暂时忽略这个细节,你的初步假设并不完全正确。

在这种情况下,不会捕获异常并且程序将终止,因此内存泄漏是学术性的。

但是,如果范围中有try/catch块,那将捕获异常,在任何一种情况下都不会发生内存泄漏。在两个示例中,a对象已完全构造。因此,抛出的异常将破坏a,并调用其析构函数。

抛出异常将展开堆栈直到捕获到异常,并且作为该进程的一部分,销毁本地范围内的所有对象,直到捕获到异常。

所以,这是一个有争议的问题。没有内存泄漏,前提是异常最终被捕获,没有人需要担心任何事情。

您展示的类大多符合RAII原则(需要复制构造函数和赋值运算符,以包装松散的末尾)。该类唯一负责的是,如果在构造函数 中抛出 ,则无论构造函数分配了什么都需要清理。

答案 1 :(得分:1)

这非常无关紧要。存在“内存泄漏”的唯一原因是程序将结束,这通常会清理内存。

在任何情况下,如果程序由于未处理的异常而退出,那么这不是类的问题。想象一下,如果你有100个类,所有这些类都需要关心一个函数(main)是否无法处理异常。