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

为什么我定义的C++自定义类中的移动赋值运算符没有被调用?

问题原因解释
  • 首先你混淆了初始化和赋值的语义:
    你写的BigInteger another = BigInteger({0, 1, 2});属于拷贝初始化范畴,不是赋值操作。=在变量声明语句中是初始化语法的一部分,不会触发operator=的调用,自然也不会先调用默认构造函数生成another对象再赋值,所以你预期里的默认构造、移动赋值流程从根本上不成立。
  • 其次是C的**复制消除(Copy Elision)**规则生效:
    即使不考虑优化,这段代码的原始语义也是:先用initializer_list构造函数生成临时BigInteger对象,再调用移动构造函数用这个临时对象构造another,最后析构临时对象。但C
    17及之后的标准强制要求编译器在这种纯右值初始化同类型对象的场景下,直接省略临时对象的创建和后续的移动构造步骤,直接用构造临时对象的参数(也就是你的{0,1,2}初始化列表)构造目标对象another。所以整个过程只有一次initializer_list构造函数调用,main函数结束时析构another,输出和你实际看到的完全一致。

验证方式

如果你关掉编译器的复制消除优化(比如GCC/Clang添加编译参数-fno-elide-constructors),就能看到未优化的原始流程输出:

initializer_list constructor
move constructor
destructor
destructor

如果想触发你预期的默认构造+移动赋值流程,需要把代码拆分为声明和赋值两步:

int main()
{
    BigInteger another; // 先默认构造
    another = BigInteger({0, 1, 2}); // 再移动赋值
}

这段代码的输出就会匹配你的预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:15:08