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



我有一个没有析构函数和构造函数的类,如下所示:

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的数据成员是智能指针,而不是普通(内置(指针,则不必在类Foo的析构函数中写入delete p

作为Anoop正确答案的附加答案:

试着";强调";使用编译器和运行时。如果发生析构函数调用,环境应该如何决定是否在指针上调用delete?它没有机会确定这一点,而且它实际上不是语言设计的工作(与C#和Java哲学形成部分对比(。指针也可以是一个非拥有者,其引用的动态分配存储应该在您的特定析构函数调用中幸存下来,即使在您的类是分配器的情况下也是可能的(通常设计不好,但允许(。

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

最新更新