当前位置: 首页 > article >正文

C++11的unique_ptr独占的智能指针

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

unique_ptr<T> myPtr(new T);
unique_ptr<T> myOtherPtr = myPtr;    ///错误,不能复制

        unique_ptr不允许复制,但可以通过函数返回给其他的unique_ptr,还可以通过std::move来转移到其他的unique_ptr,这样它本身就不再拥有原来指针的所有权了。例如:

unique_ptr<T> myPtr(new T);                     /// Okay
unique_ptr<T> myOtherPtr = std::move(myPtr);    ///Okay
unique_ptr<T> ptr = myPtr;                      ///错误,只能移动,不可复制

        unique_ptr和shared_ptr相比,unique_ptr除了独占性这个特点之外,还可以指向一个数组,代码如下:

std::unique_ptr<int []> ptr(new int[10]);
ptr[9] = 9;

        而std::shared_ptr<int []> ptr(new int [10]);是不合法的。

        unique_ptr指向的删除器和std::shared_ptr是有差别的,比如下面的写法:

std::shared_ptr<int> ptr(new int(1), [](int* p){delete p;});    ///正确
std::unique_ptr<int> ptr(new int(1), [](int* p){delete p;})     ///错误

        std::unique_ptr指定删除器的时候需要确定删除器的类型,所以不能像shared_ptr那样直接指定删除器,可以这样写:

std::unique_ptr<int, void(*)(int* )>ptr(new int(1), [](int* p){delete p;});

        上面这种写法在lambda没有捕获变量的情况下是正确的,如果捕获了变量,则会编译报错,这是因为lambda在没有捕获变量的情况下是可以直接转换为函数指针的,一旦捕获了就无法转换了。

        如果希望unique_ptr的删除器支持lambda,可以这样写:

std::unique_ptr<int, std::function<void(int*)>> ptr(new int(1),
    [&](int* p){delete p;});

        还可以自定义删除器,比如下面的代码:


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

struct MyDeleter
{
    void operator()(int* p)
    {
        cout << "delete" << endl;
        delete p;
    }
};

int main()
{
    {
        std::unique_ptr<int, MyDeleter> p(new int(1));
    }

    return 0;
}

         关于shared_ptr和unique_ptr的使用场景要根据实际应用来选择,如果希望只有一个智能指针管理资源或者管理数组就用unique_ptr,如果希望多个智能指针管理同一个资源就用shared_ptr。


http://www.kler.cn/a/137106.html

相关文章:

  • 用java造1万条数据
  • STM32, GD32 cubemx CAN 低速率125kbps 报文丢失,解决了
  • Redis篇--常见问题篇5--热Key(Hot Key,什么是热Key,服务降级,一致性哈希)
  • SQL Server 解决游标性能问题的替代方案
  • BlueLM:以2.6万亿token铸就7B参数超大规模语言模型
  • netcore 集成Prometheus
  • 同为科技(TOWE)工业连接器:保障高效、可靠、安全的电气连接
  • 【报错记录】解决使用Kotlin写的SpringBoot项目使用Aspect切面无法生效的问题
  • axios的封装之axios是基于什么封装的?
  • Web 自动化神器 TestCafe(二)—元素定位篇
  • 七大查找算法
  • 【图数据库实战】gremlin语法
  • c# IEnumerable--扩展方法
  • SD-WAN技术:重新定义网络连接方式
  • less相关
  • 基于STC12C5A60S2系列1T 8051单片机的模数芯片ADC0832实现模数转换应用
  • 【开发流程】持续集成、持续交付、持续部署
  • Android 13.0 Launcher3仿ios长按app图标实现抖动动画开始拖拽停止动画
  • Hibernate查询的方法
  • 维基百科文章爬虫和聚类【二】:KMeans
  • py Selenium来启动多个浏览器窗口或标签页,并操作它们
  • 回顾以前的java
  • 泗博MODBUS转PROFINET网关助力电子天平与西门子PLC无缝对接
  • 679 - Dropping Balls (UVA)
  • vue3定时器的清除
  • (论文阅读51-57)图像描述3 53