-1

Maybe the question is basic but I didn't found answer for that.

I will give the some examples (when Object has destructor), and I will glad to understand what happens in each one:

1)

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

I think it would not call the destructor, but someone told me that if the function has return then the destructor will be called.

2)

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

How about now? is it connected to the object instance we return?

if 1) is not calling detractor please confirm that 3) is not calling the destructor (I still think it will not, but confirming)

3)

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

If 1) is calling the destructor: if 3) was void function, does the destructor
will be called (I again think not).

Mr.O
  • 301
  • 1
  • 12

2 Answers2

2

Absolutely not. C++ is not garbage-collected like Java.

Every new has to be balanced with a delete, and you need to pass the pointer you get back from new to that call to delete. (More formally that pointer has to be the same type too, or polymorphically related).

Fortunately, C++ does provide smart pointer classes like std::unique_ptr that wrap the delete call in its destructor.

Bathsheba
  • 220,365
  • 33
  • 331
  • 451
2

In case #1, the destructor is NOT called, because the object exists in dynamic (heap) memory, so it will not be destructed until delete is called on it. Every new needs a matching delete.

The destructor WOULD be called if the object were created in automatic (stack) memory instead, eg:

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

In case #2, the destructor of the object pointed to by p is NOT called, and the return statement is returning a reference to the same object that exists in dynamic memory.

If the function returned an Object by value instead of by reference, then the return statement would make a copy, and the copy WOULD be destructed (but not the original!) when the caller is done using the returned object, eg:

Object f() {
    Object *p=new Object();
    return *p; // <-- copy made here
}

f(); // <-- ~Object() for the return value
     // is called when the ';' is reached

In case #3, again the objects being created in dynamic memory are NOT destructed automatically upon return.

In all three cases, you can use std::unique_ptr to provide automatic memory management of dynamic objects, eg:

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;
}
Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620