合成析构函数是否会破坏堆上分配的内存?

Does the synthesized destructor destroy the memory allocated on the heap?

我有一个 class 没有像这样的析构函数和构造函数:

class Foo {
public:
    Foo(int a) : p(new int(a)) {}

private:
    int *p;
};
{
    Foo a(4);
}

在这段代码之后,分配在堆上的内存会被释放吗? 或者我是否必须明确提供这样的析构函数:

class Foo {
public:
    Foo(int a) : p(new int(a)) {}
    ~Foo();

private:
    int *p;
};

Foo::~Foo() {
    delete p;
}

我们使用 new 在堆上分配的任何内存必须 始终使用关键字 delete.

释放

因此,您必须像在析构函数中所做的那样,使用关键字 delete 明确地 释放由 new 在堆上分配的内存。合成析构函数不会为你做。

请注意,如果您不想自己处理内存管理,那么您可以使用智能指针。这样你就不必自己显式地使用 delete 因为对应于智能指针的析构函数将负责释放内存。这实质上意味着如果名为 p 的数据成员是智能指针而不是普通(内置)指针,那么您 不必 编写 delete p在你的 class Foo.

的析构函数中

作为对 Anoop 正确答案的补充回答:

只是尝试“强调”编译器和运行时。如果发生析构函数调用,环境应该如何决定是否在指针上调用 delete?它没有机会确定这一点,实际上这不是语言设计的工作(部分与 C# 和 Java 哲学相反)。该指针也可以是 非拥有者 ,其引用的动态分配存储应该在您的特定析构函数调用中幸存下来,即使在您的 class 是分配器的情况下也是如此(不好一般设计但允许)。

析构函数上下文只是“看到”成员,对于这种情况,这只是先验指针,而不是可能进一步动态分配的资源。 请尝试熟悉重要的 RAII 技术,它不仅与动态内存分配有关。