为什么函数可以返回unique_ptr


从智能指针说起
对高手而言,指针是上天入地的神器;对新手而言,那简直是灾难的源泉。高级语言如Java,C#都自动管理内存,你只管new,不必操心内存释放问题。 Bjarne StroustrupC认为++加入垃圾回收机制将做不适合系统底层的开发,为此C++提倡使用RAII来管理资源。auto_ptr就是根据这种理念而诞生的智能指针,本意是想编写个效率接近原生指针,但具有资源所有权安全的智能指针。当发生赋值,拷贝构造时,所有权就发生转移。这就显的很鸡肋,不能放入STL容器中,因为它的拷贝构造和传统的拷贝构造不一样。

unique_ptr取代auto_ptr
C++11的右值引用和move语义解决了这个问题,于是乎unique_ptr取代auto_ptr。为什么unique_ptr可以放入容器呢?如:
vector<unique_ptr<Song>> v;
v.push_back(unique_ptr<Song>(new Song("B'z","Juice")));

答案是unique_ptr可以move,不能copy。它没有拷贝构造,拷贝赋值,但是有move构造,move赋值。尽管可以放入容器内,但不是所有函数都是可以用的,当然了,必要的时候可以使用std::move来将左值转化为右值。

现在,有这么一个问题,unique_ptr没有copy函数,那么,函数是如何返回unique_ptr的呢?比如C++14就有个make_unique的模板函数返回了unique_ptr。我们来看看他的实现:
template<class T,     class... Types>
unique_ptr<T> make_unique(Types&&... Args)
{
    return (unique_ptr<T>(new T(forward<Types>(Args)...)));   
}
这个函数会调用拷贝构造吗,一开始我也很迷惑,经过一番查找之后,基本可以确认不会调用拷贝构造。

RVO和NRVO
当函数返回一个对象时,理论上会产生临时变量,那必然是会导致新对象的构造和旧对象的析构,这对效率是有影响的。C++编译针对这种情况允许进行优化,哪怕是构造函数有副作用,这叫做返回值优化(RVO),返回有名字的对象叫做具名返回值优化(NRVO),就那RVO来说吧,本来是在返回时要生成临时对象的,现在构造返回对象时直接在接受返回对象的空间中构造了。假设不进行返回值优化,那么上面返回unique_ptr会不会有问题呢?也不会。因为标准允许编译器这么做:
1.如果支持move构造,那么调用move构造。
2.如果不支持move,那就调用copy构造。
3.如果不支持copy,那就报错吧。

显然的,unique_ptr是支持move构造的,unique_ptr对象可以被函数返回。
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
C++中,函数可以返回一个shared_ptr对象。可以通过以下几种方式来返回shared_ptr对象: 1. 使用make_shared函数:可以使用std::make_shared函数来创建一个shared_ptr对象,并将其作为函数返回值。例如: ```cpp std::shared_ptr<MyClass> createObject() { return std::make_shared<MyClass>("Hello", 3.14); } ``` 2. 使用new关键字:可以使用new关键字手动创建一个对象,并将其包装在shared_ptr返回。例如: ```cpp std::shared_ptr<int> createInt() { return std::shared_ptr<int>(new int(1)); } ``` 3. 使用reset函数:可以先创建一个空的shared_ptr对象,然后使用reset函数将其重新指向一个新的对象。例如: ```cpp std::shared_ptr<int> createInt() { std::shared_ptr<int> ptr; ptr.reset(new int(1)); return ptr; } ``` 无论使用哪种方式,函数返回的shared_ptr对象都可以在函数外部进行使用和管理。 #### 引用[.reference_title] - *1* *3* [C++11 解决内存泄露问题的智能指针:shared_ptrunique_ptr、weak_ptr](https://blog.csdn.net/weixin_44120785/article/details/128714630)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [智能指针shared_ptrunique_ptr、weak_ptr](https://blog.csdn.net/weixin_44477424/article/details/125902769)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值