为什么“=default”析构函数不同于隐式声明的析构函数?

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

所以我读了这个post:

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

其中讨论原因:

~Widget() = default;

不同于:

~Widget() {}

但是,“=default”的情况与隐式声明的情况不同也是事实。从某种意义上说,=default 实际上并没有给你默认值,这有点奇怪。

考虑以下程序:

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;
}

运行 该程序将打印 "Got copied",除非您注释掉默认的 ~B(),在这种情况下它将打印 "Got moved"。那么这是为什么呢?考虑到这个和隐式声明的析构函数都应该产生 "trivial destructors".

,我认为“=default”非常令人困惑

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;

现在当你说 ~B() = default; 时,虽然你仍然得到默认的析构函数,但它现在也被认为是用户声明的,因此不会有隐式定义的移动构造函数。