动态(在堆上)分配的对象的析构函数是否将在return函数中自动调用?

时间:2019-01-26 19:36:19

标签: c++

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

我将给出一些示例(当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函数,则析构函数会执行
将被称为(我再次认为不是)。

2 个答案:

答案 0 :(得分:2)

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

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

幸运的是,C ++确实提供了诸如delete之类的智能指针类,这些类将std::unique_ptr调用包装在其 destructor 中。

答案 1 :(得分:2)

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

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

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

在情况2中,未调用p指向的对象的析构函数,并且return语句正在对存在的同一对象返回引用在动态内存中。

如果该函数返回的是Object按值 ,而不是按引用的 ,则return语句将复制 < / em>,当调用者使用返回的对象完成操作时,副本将被销毁(但不是原始副本!),例如:

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;
}