Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between "= default" destructor and empty destructor?

I want to prevent the user of my class from using it as an automatic variable, so I write code like this:

class A { private:   ~A() = default; };  int main() {   A a; } 

I expect that the code won't be compiled, but g++ compiles it without error.

However, when I change the code to:

class A { private:   ~A(){} };  int main() {   A a; } 

Now, g++ gives the error that ~A() is private, as is my expectation.

What's the difference between a "= default" destructor and an empty destructor?

like image 231
delphifirst Avatar asked Jan 04 '15 04:01

delphifirst


People also ask

What does an empty destructor do?

Your destructor may look empty, but it's actually destructing the member variables. In this case, it's destructing myset , so the subsequent insert(20) is crashing. If your class had no non-POD member variables then the empty destructor would truly do nothing.

What is a default destructor?

The default destructor calls the destructors of the base class and members of the derived class. The destructors of base classes and members are called in the reverse order of the completion of their constructor: The destructor for a class object is called before destructors for members and bases are called.

How many types of destructor are there?

There has to be only one Destructor in a class. A Destructor has no return type and no parameters. If we do specify a destructor in class then, the compiler creates a default destructor.

Does the default destructor delete pointers?

Default destructors call destructors of member objects, but do NOT delete pointers to objects.


1 Answers

Your first example should not compile. This represents a bug in the compiler that it does compile. This bug is fixed in gcc 4.9 and later.

The destructor defined with = default is trivial in this case. This can be detected with std::is_trivially_destructible<A>::value.

Update

C++11 (and C++14) state that if one has a user-declared destructor (and if you don't have either user-declared move special member), then the implicit generation of the copy constructor and copy assignment operator still happen, but that behavior is deprecated. Meaning if you rely on it, your compiler might give you a deprecation warning (or might not).

Both:

~A() = default; 

and:

~A() {}; 

are user-declared, and so they have no difference with respect to this point. If you use either of these forms (and don't declare move members), you should explicitly default, explicitly delete, or explicitly provide your copy members in order to avoid relying on deprecated behavior.

If you do declare move members (with or without declaring a destructor), then the copy members are implicitly deleted.

like image 54
Howard Hinnant Avatar answered Sep 25 '22 12:09

Howard Hinnant