【问题标题】:Why is a "=default" destructor different than the implicitly declared destructor?为什么“=default”析构函数与隐式声明的析构函数不同?
【发布时间】:2020-01-21 08:02:39
【问题描述】:

所以我读了这篇文章:

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

【问题讨论】:

标签: c++ destructor


【解决方案1】:

Bonly gets created if 的隐式定义移动构造函数

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

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

【讨论】:

  • 这表明这个页面是错误的:en.cppreference.com/w/cpp/language/destructor 在平凡的析构函数下说:“析构函数不是用户提供的(意思是,它要么被隐式声明,要么显式定义为默认值)声明)”
  • @Benj 为什么?这只是列出了 trivial 析构函数的条件,而不是 defaultimplicitly-defined 析构函数。它谈论的是 user-provided 而不是 user-declared,这是一个微妙的区别。无论哪种方式,在 cppreference wiki 上谈论这种详细程度的细节可能是徒劳的,如果你想像这样真正具体,你应该直接查阅标准。
猜你喜欢
  • 2021-11-20
  • 2016-12-28
  • 2023-03-10
  • 1970-01-01
  • 2012-11-14
  • 2018-07-03
  • 2014-02-01
相关资源
最近更新 更多