使用STL容器存储智能智能的注意事项

1.使用存储unique_ptr指针类型的容器给其它容器赋值

因为unique_ptr指针的独占所引用空间的这一特性,使得在使用容器存储unique_ptr类型的智能指针的容器,给另外一个容器进行赋值操作时可能会出现问题,这里我们以vector为例来进行说明:

#include <vector>
#include <memory>

int main()
{
    std::vector<std::unique_ptr<int>> vec1{};
    //向vec1中添加3个指针元素
    vec1.emplace_back(std::unique_ptr<int>(new int(1)));
    vec1.emplace_back(std::unique_ptr<int>(new int(2)));
    vec1.emplace_back(std::unique_ptr<int>(new int(3)));

    //std::cout<<"vec1.use_count="<<vec1[0].use_count()<<std::endl;
    std::cout<<"vec1.size="<<vec1.size()<<"  capacity="<<vec.capacity()<<std::endl;

    //1.调用swap()方法可以,这其实相当于move
    std::vector<std::unique_ptr<int>> vec2{};
    vec2.swap(vec1);

    //2.拷贝构造的方法不可以,因为这里是copy,不能用unique_ptr给另外的unique_ptr赋值
    //std::vector<std::unique_ptr<int>> vec2(vec1);  //编译失败

    //3.assign的方法也不可以,也是copy
    //vec2.assign(vec1.begin(), vec1.begin() + 2);    //编译失败

    return 0;
}

上面的代码中我们定义了一个vector<unique_ptr<int>>类型的vec1,然后向其中通过emplace_back()方法向其中添加了三个成员,然后使用三种方法给另一个同类型的vec2进行赋值,其中:

(1)方法一:调用vec2.swap(vec1)方法ok,因为这其实相当于移动语义,将vec1中shared_ptr元素所引用空间的使用权转移给了vec2中的元素,空间引用计数始终为1,没有问题。

(2)方法二:vec2(vec1);使用vec1给vec2进行初始化,本质类似拷贝构造函数,导致vec1中shared_ptr元素给vec2中的元素赋值,而unique_ptr不支持,因为引用计数使用为1,直接编译失败。

(3)方法三:vec2.assign(vec1.begin(), vec.end()); 原理也是copy,和方法二一样,直接编译失败。

编译失败报错如下:

知识点:如果上面的unique_ptr换成shared_ptr,则在操作上都ok。所以在使用STL容器存储unique_ptr时需要格外注意。

2.unique_ptr模板类中的成员函数

unique_ptr模板类的用法中虽然重载了"=赋值运算符",但只能是使用用nullptr或者 右值unique_ptr来进行赋值。

unique_ptr指针的赋值操作:

    std::unique_ptr<int> ptr1(new int(3));
    //编译失败
    std::unique_ptr<int> ptr2(ptr1);

    //ok,利用移动语义实现赋值
    std::unique_ptr<int> ptr3(std::move(ptr1));

    //ok,swap()方法本质也是移动语义
    std::unique_ptr<int> ptr4 = nullptr;
    ptr4.swap(ptr1);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值