合成析构函数是否会破坏堆上分配的内存?
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 技术,它不仅与动态内存分配有关。
我有一个 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 技术,它不仅与动态内存分配有关。