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

std::move与临时对象生命周期:代码执行顺序及析构时机问询

为什么被std::move转换的临时对象会立即析构?

先看代码:

struct Foo {
    ~Foo() {
        std::cout << "1";
    }
};
int main() {
    const Foo& bar = Foo();
    const Foo& baz = std::move(Foo());
    std::cout << "2";
}

这段代码的输出是121。你已经理解main结束时析构bar绑定的临时对象会输出最后一个1,下面解释为什么std::move(Foo())对应的临时对象会立即析构:

核心规则:临时对象生命周期延长的条件

C++标准明确规定:只有当引用直接绑定到临时对象本身时,临时对象的生命周期才会被延长至引用的生命周期结束。如果是通过中间引用(比如std::move返回的右值引用)间接绑定,生命周期延长规则不生效。

逐行分析执行顺序

  1. const Foo& bar = Foo();

    • Foo()创建一个临时对象。
    • 这个临时对象被直接绑定到const Foo&类型的bar,触发生命周期延长:临时对象的生命周期会和bar保持一致,直到main函数结束才析构。
  2. const Foo& baz = std::move(Foo());

    • 先执行Foo(),创建第二个临时对象。
    • std::move接收这个临时对象,返回指向它的Foo&&右值引用(注意std::move仅做类型转换,不实际移动数据)。
    • 这里baz绑定的是std::move返回的右值引用,而非直接绑定到Foo()创建的临时对象,因此生命周期延长规则不触发。
    • 该临时对象会在当前完整表达式结束时(即这条语句的分号处)立即析构,输出第一个1。
  3. std::cout << "2";

    • 输出2,此时控制台内容为12。
  4. main函数结束

    • bar的生命周期结束,它绑定的临时对象被析构,输出最后一个1,最终输出为121。

析构函数的调用位置

被std::move处理的临时对象,其析构函数在const Foo& baz = std::move(Foo());语句执行完毕(分号处)时立即调用;bar绑定的临时对象,析构函数在main函数代码块结束(}处)时调用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:25:53