动态分配(堆上)的对象的析构函数是否会在返回函数中自动调用

Does the destructor of an object allocated dynamically (on heap) will be called automatically in return function?

本文关键字:返回 函数 调用 是否 堆上 对象 动态分配 析构函数      更新时间:2023-10-16

也许这个问题很基本,但我没有找到答案。

我将给出一些例子(当Object有析构函数时),我会很高兴地理解每一个例子中会发生什么:

1)

int f (){
Object *p=new Object();
int something=5;
return something;
}

我想它不会调用析构函数,但有人告诉我,如果函数已经返回,那么析构函数就会被调用。

2)

Object & f (){
Object *p=new Object();
return *p;
}

现在怎么样?它是否连接到我们返回的对象实例?

如果1)没有调用诋毁者,请确认3)没有调用析构函数(我仍然认为不会,但确认)

3)

int f (){
for(int i=0; i<10; i++){
Object *p=new Object();
}
int something=5;
return something;
}

如果1)正在调用析构函数:如果3)是void函数,那么析构函数
是否会被调用(我再次认为不会)。

在情况#1中,不调用析构函数,因为对象存在于动态(堆)内存中,所以在调用delete之前不会对其进行析构函数。每个new都需要一个匹配的delete

如果对象是在自动(堆栈)内存中创建的,则会调用析构函数,例如:

int f() {
Object p; // <-- no 'new'
int something=5;
return something;
} // <-- ~Object() is called here

在情况#2中,p指向的对象的析构函数不会被调用,return语句将向动态内存中存在的同一对象返回引用

如果函数通过值而不是通过引用返回Object,则return语句将生成副本,并且当调用方使用返回的对象(例如:

Object f() {
Object *p=new Object();
return *p; // <-- copy made here
}
f(); // <-- ~Object() for the return value
// is called when the ';' is reached

在情况#3中,在动态内存中创建的对象在返回时不会自动销毁。

在这三种情况下,您都可以使用std::unique_ptr来提供动态对象的自动内存管理,例如:

int f() {
std::unique_ptr<Object> p(new Object);
int something=5;
return something;
} // <-- ~unique_ptr() is called here

std::unique_ptr<Object> f() {
std::unique_ptr<Object> p(new Object);
return std::move(p);
} // <-- ~unique_ptr() for p is called here
f(); // <-- ~unique_ptr() for the return value
// is called when the ';' is reached

int f() {
for(int i=0; i<10; i++) {
std::unique_ptr<Object> p(new Object);
} // <-- ~unique_ptr() is called here
int something=5;
return something;
}

绝对不是。C++不像Java那样垃圾收集。

每个new都必须与delete平衡,并且您需要将从new返回的指针传递给delete的调用。(更正式地说,指针也必须是相同的类型,或者是多态相关的)。

幸运的是,C++确实提供了智能指针类,如std::unique_ptr,它们将delete调用封装在其析构函数中。