3

Is there any possible situation where using standard new/delete isn't enough and we need to explicitly call a destructor, like pA->~A()?

I think it's only necessary in some resource management classes, but usually is a bad idea. The destructor is called automatically at the end of scope, so why would I want to explicitly call it myself?

An explanation with an example would be great!

Oleksiy
  • 37,477
  • 22
  • 74
  • 122

2 Answers2

7

In C++11 you can have a union with types needing a destructor. Since the compiler doesn't track which type is currently active, you'll need to explicitly destroy the current member when replacing the currently active member or when destroying the union.

In 9.5 [class.union] paragraph 4 the standard uses the following example code to switch from the current active member m to the newly active member n:

u.m.~M();
new (&u.n) N;
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • +1 TIL that you can placement-`new` (and manually destruct) `union` members, at least in C++11. I seem to recall that this (and generally using non-POD types in `union`s) is UB in C++03.... – C. K. Young Sep 01 '13 at 00:27
  • @ChrisJester-Young: I don't think it is undefined behavior in C++03: I think in C++03 the compiler is required to create a diagnostic when trying to use a non-POD as a member of a `union`. – Dietmar Kühl Sep 01 '13 at 00:29
6

Another instance where explicit destructor calls are used is with objects that were manually constructed using placement new.

Say you were trying to use a malloc/free-compatible API (e.g., for interaction with C clients that allow specifying custom C-style allocators):

void* buf = malloc(sizeof (MyType));
if (buf) {
    MyType* foo = new (buf) MyType;
    // ...
    foo->~MyType();
    free(buf);
}

(Though, in this instance, it's better to just use a shared_ptr or unique_ptr with a custom deleter.)

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • Do you mean calling `delete`? Can you give an example please? – Oleksiy Sep 01 '13 at 00:19
  • @Oleksiy You can only use `delete` for objects allocated using `new`. I've provided an example where the memory underlying an object was allocated using `malloc` instead. – C. K. Young Sep 01 '13 at 00:25
  • calling delete foo wouldn't be equivalent to foo->~MyType(); free(buf); ? – 4pie0 Sep 01 '13 at 00:45
  • 1
    @computer No, `delete` does not ([necessarily](http://stackoverflow.com/a/240308/13)) use `free`, just like `new` doesn't (necessarily) use `malloc`. The C++ system has its own allocator that the default `new` and `delete` use. In any case, this is all beside the point, since my example is supposed to be generalisable to the case where C clients are specifying custom allocators (that use a `malloc`/`free` interface). – C. K. Young Sep 01 '13 at 00:45
  • but delete foo frees memory also, so frees buf, where MyType is allocated, isn't it? I mean, if I did delete foo, would this be wrong? – 4pie0 Sep 01 '13 at 00:50
  • 1
    @computer You cannot use `delete` on objects whose memory was allocated using `malloc`. That is because `malloc` may be using a different area of memory from what `new` uses. `new` is [allowed, but not required](http://stackoverflow.com/a/240308/13), to use `malloc` behind the scenes. – C. K. Young Sep 01 '13 at 00:51
  • I know this, but here I can see foo is created with new, right? Yes, this is placement new in fact, and this is the reason why I cannot delete foo? – 4pie0 Sep 01 '13 at 00:53
  • @computer Yes, that's the reason. Placement `new` doesn't allocate anything. It just allows you to specify a pointer to construct an object at, which must already point to valid memory. – C. K. Young Sep 01 '13 at 00:56