为什么“=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”非常令人困惑
的隐式定义移动构造函数
- 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;
时,虽然你仍然得到默认的析构函数,但它现在也被认为是用户声明的,因此不会有隐式定义的移动构造函数。
所以我读了这个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”非常令人困惑
- 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;
时,虽然你仍然得到默认的析构函数,但它现在也被认为是用户声明的,因此不会有隐式定义的移动构造函数。