c++ - 为什么“=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”非常令人困惑。
解决方案
仅在以下情况下创建隐式定义的移动构造函数B
- 没有用户声明的复制构造函数;
- 没有用户声明的复制赋值运算符;
- 没有用户声明的移动赋值运算符;
- 没有用户声明的析构函数;
现在,当您说 时~B() = default;
,虽然您仍然获得默认析构函数,但它现在也被认为是用户声明的,因此不会有隐式定义的移动构造函数。
推荐阅读
- c# - C# TcpClient 错误地读取了前一个 Write 的响应
- django - 如何为 LiveServerTestCase 加载夹具
- json - 仅向 Suricata EVE 输出规则警报
- php - PHP - array_map 2列并按键删除重复行
- kubernetes - 将 JSON 补丁应用到 Kubernetes 自定义资源时出错
- python - 如何找到每天一次登录的最大唯一用户数?
- flutter - 颤振本地化加载后如何重新加载应用程序
- docker - 如何从 docker 注册表中删除空存储库
- algorithm - 在排名(排序)列表上执行前缀搜索的有效方法?
- symfony - Composer 更新成功,但 Composer 安装在创建的锁定文件上失败