What does empty destructor do?

2019-05-06 22:12发布

I heard that empty destructor doesn't do anything and calling it doesn't remove the object. But in the code:

#include <iostream>
#include <set>


class a
{
public:
    ~a() 
    {}
std::set <int> myset;
};

int main()
{
a object;
object.myset.insert(55);
object.~a();
object.myset.insert(20);
std::cout << object.myset.size();
}

I get: "* glibc detected * /.app: double free or corruption (fasttop):" and then "ABORT".

If it matters I have c++11 flag enabled. So what does empty constructor actually do? It does something and I read it doesn't.

3条回答
Root(大扎)
2楼-- · 2019-05-06 22:16

Your question mentions a couple different issues.

First, there's the error message. The "Double free" is probably because the destructor is getting called twice: once by you, and once by the C++ runtime when the variable is no longer in scope (at the closing brace of your main function).

Second, there's your question about the empty destructor not removing the object. Indeed it does not remove the object from memory, but it DOES destroy its member variables. So after your manual call to the destructor, the memory for object is still allocated, but myset is no longer valid.

查看更多
Fickle 薄情
3楼-- · 2019-05-06 22:17

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.

查看更多
你好瞎i
4楼-- · 2019-05-06 22:23

Destructor is called when going out of scope. I would highly recommend not calling the destructor, and then attempting to access members or member functions of the parent class. Since your class has member variables myset, it's deallocating those when being manually called, hence the segmentation error.

Think of the destructor as the "clean up" when you're absolutely done with your object. Under no circumstances should you call it manually.

Pseudocode:

class MyClass {
public:
  MyClass() {
    std::cout << "Constructor" << std::endl;
  }

  ~MyClass() {
     std::cout << "~Destructor" << std::endl;
   }
}

int main(int argc, char** argv) {
   MyClass myClass;
   return 0;
}

You should see this output:

Constructor

~Destructor

As you can see, no manual call is needed.

查看更多
登录 后发表回答