APOLLO学习C++基础之一[unique_ptr智能指针]

                   APOLLO学习C++基础之一[unique_ptr智能指针]

     在学习apollo过程中,经常碰到这样的指针,unique_ptr,就是我要讲的智能指针,(当然,对于C++的高手来说,就是小菜一碟,对于经常使用C的我,当然有点陌生,所以就一点一点的学习,一点一点的积累。)导航器指针(navigator_ptr_)、监控日志类对象(monitor_logger_)、路由配置类对象(routing_conf_)、高精地图指针(hdmap_)。注意navigator_ptr_使用C++标准库的唯一性智能指针unique_ptr包装。

智能指针其优点在于:

  1)智能指针能够帮助我们处理资源泄露问题;

  2)它也能够帮我们处理空悬指针的问题;

  3)它还能够帮我们处理比较隐晦的由异常造成的资源泄露。

       4)是不用人工管理内存;

      5)确保数据的唯一性。如导航器指针(std::unique_ptr<Navigator> navigator_ptr_)


1.智能指针unique_ptr的用法

unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法:

    std::unique_ptr<T> myPtr(new T);
    std::unique_ptr<T> myOtherPtr = myPtr; // 错误用法

但是unique_ptr允许通过函数返回给其他的unique_ptr,还可以通过std::move来转移到其他的unique_ptr,注意,这时它本身就不再拥有原来指针的所有权了。相比于auto_ptr而言,unique_ptr是显示的转移,而不是莫名其妙的报废,因为auto_ptr调用拷贝构造函数后,原来的对象就失效了。

    std::unique_ptr<T> myPtr(new T);
    std::unique_ptr<T> myOtherPtr = std::move(myPtr); //这样使用是正确的

对于一般的程序使用std::unique_ptr就够了,如果是多线程方面,可能存在共同使用的问题,可以使用std::shared_ptr,注意不要引起循环引用。

2.管理数组指针

因为unique_ptr有unique_ptr< X[ ] >重载版本,销毁动态对象时调用delete[],所以可以用unique_ptr来管理数组指针。

unique_ptr< Test[ ] > uptr1(new Test[3]);
//注意 unique_ptr<Test> uptr3(new Test[3]);是不对的
unique_ptr<int[]> uptr2(new int[5]);

3.做容器(vector, list, map)元素

vector<unique_ptr<int> > vec;
unique_ptr<int> ptr1(new int(3));
vec.push_back(std::move(ptr1));
//vec.push_back(ptr1); //由于禁止复制这样不行

unique_ptr类中有get()、reset()、release()等函数。

get(): 获得原生指针

reset():重置,显式释放资源

reset(new XX):重置,重新指定对象

release():释放所有权到某一原生指针上

另外可以通过std::move将所有权由一个unique_ptr对象转移到另一个unique_ptr对象上,具体见下例。


#include <iostream>
#include <memory>
using namespace std;

int main()
{
    //1. unique_ptr的创建
    //1.1)创建空的,然后利用reset指定对象
    unique_ptr<int> up1; 
    up1.reset(new int(3)); 
    //1.2)通过构造函数在创建时指定动态对象
    unique_ptr<int> up2(new int(4));

    //2. 获得原生指针(Getting raw pointer )
    int* p = up1.get();

    //3.所有权的变化
    //3.1)释放所有权,执行后变为empty
    int *p1 = up1.release();
    //3.2)转移所有权,执行后变为empty
    unique_ptr<int> up3 = std::move(up2);

    //4.显式释放资源
    up3.reset();

    return 0;
}

4.禁止赋值和复制

  unique_ptr禁止赋值和复制,“唯一”地拥有其所指对象,同一时刻只能有一个unique_ptr实例指向给定对象。也就是说模板类unique_ptr的copy构造函数以及等号(“=”)操作符是无法使用的。

  通过禁止复制和赋值可以较好的改善auto_ptr的所有权转移问题。下面是其禁止复制和赋值的例子:

#include <iostream>
#include <memory>
using namespace std;

void Fun1( unique_ptr<int> up )
{
}

int main()
{
    unique_ptr<int> up1 = unique_ptr<int>(new int(10));

    //不允许复制(Copy construction is not allowed),所以以下三个均错误
    unique_ptr<int> up2 = up1;  // 错误
    unique_ptr<int> up3(up1);   // 错误
    Fun1(up1);                  // 错误

    //不允许赋值('='),所以下面错误
    unique_ptr<int> up4;
    up4 = up1;                  // 错误

    return 0;
}

 

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值