You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

显式声明默认行为析构函数后,类是否仍生成默认移动构造函数?

C++显式声明析构函数后默认移动构造函数的生成规则

结论

当你显式声明了类的析构函数(哪怕它的行为和默认析构完全一致),编译器不会自动生成默认移动构造函数,这是C++11及后续标准明确规定的规则。

规则依据

C++标准规定:如果类显式声明了拷贝构造函数、拷贝赋值运算符、析构函数中的任意一个,编译器将不再自动生成默认的移动构造函数和移动赋值运算符。显式声明析构函数会触发这个抑制逻辑,和析构函数的具体实现无关。

你的测试代码分析

你写的测试代码其实已经能验证这个结论:

  • 当注释掉~B(){}时,编译器会为B生成默认移动构造函数,它会调用成员变量A的移动构造,运行时会输出a move ctor.。
  • 当打开~B(){}的注释后,编译器不再生成B的移动构造函数。此时B b2(std::move(b))会尝试寻找可用的构造函数,因为编译器仍会生成默认拷贝构造函数(显式声明析构不会抑制拷贝构造),所以会调用B的默认拷贝构造,进而触发A的拷贝构造,运行时输出a copy ctor.——这就说明移动构造没有被生成。

更严谨的编译期验证方法

除了运行时输出,还可以用C++标准库的类型特性做编译期检查,直接验证类是否可移动构造:

#include <type_traits>

class B {
public:
    ~B() {}
};

// 编译期断言:B应该不可移动构造
static_assert(std::is_move_constructible_v<B> == false, "B is move constructible, which contradicts the rule");

如果这段代码能正常编译通过,就证明B确实没有默认移动构造函数;如果编译失败(断言触发),则说明规则未生效(这种情况通常是编译器版本不支持C++11及以上标准)。

内容的提问来源于stack exchange,提问作者akanesora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 18:57:07