首页 > 解决方案 > 为什么“=default”析构函数与隐式声明的析构函数不同?

问题描述

所以我读了这篇文章:

对于默认构造函数和析构函数,“=default”与“{}”有何不同?

其中讨论了原因:

~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 mapped”,除非您注释掉默认的 ~B(),在这种情况下它将打印“Gotmoved”。那么这是为什么呢?考虑到这个和隐式声明的析构函数都应该产生“微不足道的析构函数”,我认为“=default”非常令人困惑。

标签: c++destructor

解决方案


仅在以下情况下创建隐式定义的移动构造函数B

  • 没有用户声明的复制构造函数;
  • 没有用户声明的复制赋值运算符;
  • 没有用户声明的移动赋值运算符;
  • 没有用户声明的析构函数;

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


推荐阅读