Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a "=default" destructor different than the implicitly declared destructor?

Tags:

c++

destructor

So I read this post:

How is "=default" different from "{}" for default constructor and destructor?

Which discusses why:

~Widget() = default;

Isn't the same as:

~Widget() {}

However, it's also true that the "=default" case is different than the implicitly declared case. In some sense, =default doesn't actually give you the default, which is kinda odd.

Consider the following program:

class A
{
public:
    A(std::string str)
    {
        m_str = str;
    } 

    ~A() = default;

    A(A const& rhs)
    {
        printf("Got copied\n");
        m_str = rhs.m_str;
    }

    A(A&& rhs)
    {
        printf("Got moved\n");
        m_str = std::move(rhs.m_str);
    }

    std::string m_str;
};

class B 
{
public:
    B(std::string test) : m_a(test)
    {
    }

    ~B() = default;

    A m_a;
};

int main()
{
    B b("hello world");
    B b2(std::move(b));

    return 0;
}

Running this program will print "Got copied", unless you comment out the defaulted ~B() in which case it will print "Got moved". So why is this? I think "=default" is pretty confusing considering both this and the implicitly declared destructor are supposed to produce "trivial destructors".

like image 234
Benj Avatar asked Sep 20 '19 09:09

Benj


People also ask

When a destructor is implicitly declared and implicitly defined for a class?

If no user-defined destructor exists for a class and one is needed, the compiler implicitly declares a destructor. This implicitly declared destructor is an inline public member of its class.

What is the purpose of default destructor?

Destructors are usually used to deallocate memory and do other cleanup for a class object and its class members when the object is destroyed. A destructor is called for a class object when that object passes out of scope or is explicitly deleted.

What happens if you don't define a destructor?

A destructor has the same name as the class, preceded by a tilde ( ~ ). For example, the destructor for class String is declared: ~String() . If you do not define a destructor, the compiler will provide a default one; for many classes this is sufficient.

Does default destructor call Delete?

Delete invokes the destructor In turn, since ListItem has member String val, the destructor for String is invoked. Default destructors call destructors of member objects, but do NOT delete pointers to objects. Thus, we need to write destructors that explicitly call delete.


1 Answers

The implicitly-defined move constructor for B only gets created if

  • there are no user-declared copy constructors;
  • there are no user-declared copy assignment operators;
  • there are no user-declared move assignment operators;
  • there are no user-declared destructors;

Now when you say ~B() = default;, while you still get the default destructor, it's now also considered user-declared, and thus there won't be an implicitly defined move constructor.

like image 68
orlp Avatar answered Sep 27 '22 22:09

orlp