1

I know that I can declare a destructor =delete or private in order to prevent the program from implicitly deleting the object at the end of scope. I also know that if it's private, I can have a member function that can explicitly call the destructor whenever I call it: void kill() { this–>~A(); }

My questions are:

  • Why would I ever want to prevent implicit destruction? Please give an example

  • What would =delete do? Does it make sure the destructor never runs? So the object will exist forever outside its scope?

Oleksiy
  • 37,477
  • 22
  • 74
  • 122
  • I suppose if you had a POD that you only wanted to be used with `malloc`/`free`, but that seems a bit silly at first thought. – chris Sep 17 '13 at 01:52
  • The delete'd destructor I don't know, but the use of private destructor could be used to prevent a user calling delete on an object returned from a singleton. – goji Sep 17 '13 at 02:01
  • Well, you might want to close a stream before destroying it.. – Dru Sep 17 '13 at 02:13
  • @Dru couldn't you close it in the destructor? – Oleksiy Sep 17 '13 at 02:14
  • @Oleksiy not if you needed to make polymorphic calls from destructors further up the ancestry. – paddy Sep 17 '13 at 02:19
  • @paddy I'm not yet at the level to be able to fully understand what you just said :) Do you mean the base classes would need to call something from their destructors? If you could provide an example that would be great and would clear things up! – Oleksiy Sep 17 '13 at 02:30
  • the default destructor destructor won't call stream.close, so you must prevent the default destructor by providing one that closes the stream... – Dru Sep 17 '13 at 02:43

1 Answers1

1

Idioms like a private destructor are generally used to prevent other programmers from performing certain operations with your type. A private destructor in particular prevents the following:

  • Declaration of a type of your instance on the stack
  • Manual deletion of an instance of your type via the delete keyword
  • Manual destructor calls

Doing any of these will raise a compile error that is not trivial to work around. The error is usually a message from the author to a user that they should not perform one or all of these operations, instead the author may want them to:

  • Call factory functions to destroy instances of this type (typically coupled with private constructors). Providing extra context on construction and destruction can provide optimization opportunities or prevent API misuse when a batched operation is much more efficient than a "one off" allocation.
  • Not allocate any instances of this type (maybe it's a singleton)

Consider writing a type that manages a hardware interface, allowing the user to simply delete the instance might leave hardware in an undesirable state - so why even allow it? Yes, at some point the API can be built up to abstract away this difficulty - but at some basic level 'fragile' functionality needs to be exposed.

=delete is the 'new' bullet proof way of preventing user error. Unlike the private copy constructor it cannot be circumvented via the 'friend' keyword. It also tends to read better, in that it tells the user of the code in a consistent fashion that this feature is not available. My understanding is that =delete was introduced in c++11 as a replacement for the "no copy/no delete idioms".

Community
  • 1
  • 1
Dan O
  • 4,323
  • 5
  • 29
  • 44