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返回的右值引用)间接绑定,生命周期延长规则不生效。
逐行分析执行顺序
const Foo& bar = Foo();Foo()创建一个临时对象。- 这个临时对象被直接绑定到
const Foo&类型的bar,触发生命周期延长:临时对象的生命周期会和bar保持一致,直到main函数结束才析构。
const Foo& baz = std::move(Foo());- 先执行
Foo(),创建第二个临时对象。 std::move接收这个临时对象,返回指向它的Foo&&右值引用(注意std::move仅做类型转换,不实际移动数据)。- 这里
baz绑定的是std::move返回的右值引用,而非直接绑定到Foo()创建的临时对象,因此生命周期延长规则不触发。 - 该临时对象会在当前完整表达式结束时(即这条语句的分号处)立即析构,输出第一个
1。
- 先执行
std::cout << "2";- 输出
2,此时控制台内容为12。
- 输出
main函数结束bar的生命周期结束,它绑定的临时对象被析构,输出最后一个1,最终输出为121。
析构函数的调用位置
被std::move处理的临时对象,其析构函数在const Foo& baz = std::move(Foo());语句执行完毕(分号处)时立即调用;bar绑定的临时对象,析构函数在main函数代码块结束(}处)时调用。
内容的提问来源于stack exchange,提问作者Darryl Jordan
相关产品推荐
相关产品推荐

