对纯右值调用std::move是否会提前销毁对应对象?
问题现象解释
核心前置知识
- C++的临时对象生命周期延长规则:当纯右值临时对象直接绑定到引用(const左值引用、右值引用)时,临时对象的生命周期会延长到和引用变量的生命周期一致。
std::move本质是语法糖,等价于static_cast<T&&>(参数),它本身不会产生新对象,也不会修改原对象,仅返回指向入参的右值引用,不会触发生命周期延长规则。
两种写法的行为差异
第一种写法:Obj&& myObj1 = std::move(Obj(1,"lost"));
你的判断完全正确,作为入参的Obj(1, "lost")临时对象会在std::move所在的完整表达式结束后直接销毁:
- 生成
Obj(1, "lost")临时纯右值,作为实参传入std::move std::move返回指向该临时对象的右值引用,赋值给myObj1- 该完整表达式(整行赋值语句)执行结束,
Obj(1,"lost")临时对象没有直接绑定到引用(中间经过了std::move的返回值传递),不会触发生命周期延长,直接调用析构函数 - 后续调用
print(myObj1)时访问的是悬垂引用,属于未定义行为,你这里打印空值是未定义行为的一种表现。
第二种写法:Obj&& myObj2 = Obj(2,"keep");
这里临时对象直接绑定到右值引用myObj2,触发生命周期延长规则:
- 生成
Obj(2, "keep")临时纯右值,直接绑定到myObj2 - 临时对象生命周期延长到和
myObj2一致,直到作用域结束才会析构 - 后续
print(myObj2)访问合法,结果正常。
为什么会有回答说第一种写法无额外影响?
这类说法的适用场景是把std::move(临时对象)直接作为初始化/传参的右值使用,比如:
Obj o = std::move(Obj(1, "test"));
这种场景下整个初始化表达式结束前临时对象不会销毁,移动构造会在临时对象销毁前完成,没有悬垂风险,看起来确实没有额外影响,但和你当前把返回的右值引用绑定到自定义引用变量的场景完全不同。
内容的提问来源于stack exchange,提问作者Pan
相关产品推荐
相关产品推荐

