C++:不要返回局部作用域内的引用,即使右值引用也不能延长它的生命周期

此文章首发于本人知乎https://zhuanlan.zhihu.com/p/81547559。

struct A {
  A() : log{"default"} { cout << "A\n"; }
  A(const A&) : log{"copy"} { cout << "A&\n"; }
  A(A&&) : log{"move"} { cout << "A&&\n"; }
  ~A() { cout << "~A\n"; }

  string log;
};

A create() {
  A a;
  return std::move(a);
}

A&& create_rref() {
  A a;
  return std::move(a);
}

int main() {
  cout << "A create:\n";
  auto a1 = create();
  cout << a1.log << "\n";
  cout << "A&& create_rref\n";
  auto&& a2 = create_rref();
  cout << a2.log << "\n";
  cout << "End\n";
}

运行结果:

在这里插入图片描述

可以看到 a2.log 已经不是预期的值了。

此时有个坑,如果定义函数为返回右值引用,也就是 A&& create_rref(); 那么返回的结果就会引用到函数作用域内产生的对象中,没有调用移动构造函数,没有构造出新的对象,而是指向了那个即将被销毁的对象。所以函数结束的时候,可以看到析构函数的调用,作用域内对象销毁,这个右值引用也就为空了,并没有延续函数作用域内部的局部变量的声明周期,因此在这个引用上的操作也就十分危险。

如果是返回的是 A,也就是函数为 A create(); 那么在 return 的时候就会调用移动构造函数,创造出新的对象,随后函数作用域内部对象销毁,但是仍旧能够正常使用。
所以在函数作用域创建 unique_ptr 的时候,千万不要返回 std::move(up) 和右值引用。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值