c++ - 类指针成员和异常处理

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

假设我们有一个如下所示的类:

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/

相关文章:

在 Windows 中编译的 C++ 程序产生不同的输出

C++ 不合格名称查找 : different structure size in different cpp's leading to operator new allocating less memory than constructor processes?

函数指针的 C 动态数组,具有动态指定的参数

c - 哪种方式更好,类型更安全?

C++ 无意义错误 : c2629 "Unexpected class", c2065: 'ceil' 未声明的标识符

c++ - 在单个节点上,我是否应该选择 MPI 而不是其他进程间机制?

来自指针回溯的 C++ 段错误

c - 函数参数分配?

c++ - Qt中删除QStringList

c++ - 临时变量被重载的 + 和 += 运算符破坏