ZhiBing's blog(码上看世界) ZhiBing's blog(码上看世界)
首页
  • Linux工具链

    • shell命令
  • 构建

    • CMake
    • Makefile
  • 版本管理

    • Git
    • Github
  • IDE及工具

    • vscode
    • CLion
  • 设计模式

    • 设计原则
  • 编程语言

    • C++
    • Go
    • Python
    • Shell
  • 调试

    • gdb
  • 开发者测试

    • gtest
  • 系统支撑

    • 操作系统
  • 性能优化

    • 编译优化选项
    • perf
    • valgrind
  • 容器

    • Docker
  • 微服务

    • Rancher
  • 其他
  • 随笔
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)

ZhiBing Zheng

时间会回答成长
首页
  • Linux工具链

    • shell命令
  • 构建

    • CMake
    • Makefile
  • 版本管理

    • Git
    • Github
  • IDE及工具

    • vscode
    • CLion
  • 设计模式

    • 设计原则
  • 编程语言

    • C++
    • Go
    • Python
    • Shell
  • 调试

    • gdb
  • 开发者测试

    • gtest
  • 系统支撑

    • 操作系统
  • 性能优化

    • 编译优化选项
    • perf
    • valgrind
  • 容器

    • Docker
  • 微服务

    • Rancher
  • 其他
  • 随笔
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)
  • 编程语言

    • C++

      • shared_ptr(智能指针)
      • unique_ptr
      • bind函数
      • cout
      • C++ main函数的传入参数(argc, argv)
      • GLog使用
      • signals2
      • 编译期分派
      • 成员函数的调用效率
      • 返回值优化
      • 函数调用栈
      • 空类大小
      • 指针和数组的区别
      • 遵守三五原则
      • const限定符
      • static限定符
      • virtual限定符
      • 常用的CXX_FLAGS
      • 模版之AnyType
      • 模版之编译期断言
      • 模版之变参模板
    • Go

    • Python

    • shell

    • Rust

  • 调试

  • 开发者测试

  • 系统支撑

  • 性能优化

  • 通用领域
  • 编程语言
  • C++
zhengzhibing
2022-06-10

unique_ptr

# unique_ptr(智能指针)

智能指针是用于帮助管理动态内存分配的智能指针模板,其目的是为了帮助解决程序在堆中分配了内存,由于程序员忘记释放内存而导致的内存泄露问题。

unique_ptr智能指针模板定义了类似指针的对象,可以将 new 获得的地址赋值给他们,当智能指针过期的时候,其析构函数将使用 delete 来释放内存。因此,如果将 new 返回的地址赋值给这些对象,将无需记住稍后要释放这些内存:在智能指针过期的时候,这些内存将自动被释放。

unique_ptr 与 shared_ptr 的区别从单词就可以看出来,unnque_ptr 强调的是独一无二,在某一时刻只能有一个 unique_ptr 指向特定的对象。当 unique_ptr 销毁时,它所指的对象也会被销毁。

与 shared_ptr 一样,unique_ptr 初始化必须直接初始化,不支持隐式转换。与 shared_ptr 不同的是,unique_ptr 不支持拷贝和赋值操作。

unique_ptr<int> p1; // 可以指向一个int的unique_ptr
p1 = unique_ptr<int>(new int(11)); // allowed; 支持移动赋值
p1 = new int(10); // not allowed! 不支持隐式转换
unique_ptr<int> p2(new int(23)); // allowed! 支持移动拷贝
unique_ptr<int> p3(p2) // not allowed! 不支持普通的拷贝
p1 = p2; // not allowed! 不支持普通赋值
1
2
3
4
5
6

以上的特点都是印证了一点:unique_ptr 对它所指向的对象拥有独一无二的主权。这一特点在函数返回一个 unique_ptr 中也有体现。我们可以拷贝或者赋值一个即将被销毁的 unique_ptr.

虽然我们不能拷贝或者赋值 unique_ptr,但可以通过 release 或者 reset 将指针的所有权转移。

unique_ptr<int> p1(new int(10));
unique_ptr<int> p2(new int(48));
p1.reset(); // 释放p1指向的内存, p1置空
int *pt = p2.release(); // p2放弃对指针的控制权,返回一个普通指针,并将p2置成空。
p1.reset(pt); // p1获得pt的控制权,如果p1对其它指针有控制权,那么就放弃原来的控制权。
p2 = unique_ptr<int>(new int(21));
p1 = nullptr;
// same as:
// p1.reset();
p2.reset(nullptr);
// same as:
// p2 = nullptr;

1
2
3
4
5
6
7
8
9
10
11
12
13

当我们使用 release 函数,收回智能指针对原来管理对象的所有权时,并不会释放内存,因为它返回了一个常规指针,这时需要程序去负责资源的释放。

unique_ptr<int> ptr(new int(10));
ptr.release(); // 错误,资源没有释放,并且丢失了常规指针
auto p = ptr.release(); // 正确,但是需要记住delete p;
delete p;
1
2
3
4

类似于 shared_ptr, unique_ptr 默认情况下用 delete 释放它指向的对象。同样我们可以重载一个删除器,但是 unique_ptr 管理删除器的方式与 shared_ptr 不一样。重载一个 unique_ptr 中的删除器会影响到 unique_ptr 类型以及如何构造该类型的对象。所以我们需要在尖括号中指名删除器的类型。我们需要使用 decltype 指名函数指针的类型,由于 decltype(selfdel)返回一个函数类型,所以需要加一个*指名我们在使用该类型的一个指针。

// unique_ptr<objT, delT>p(new objT, fcn);
void selfdel(int *p){
    cout << "delete..." << endl;
    delete p;
}

unique_ptr<int, decltype(selfdel)*> ptr(new int(10), selfdel);

1
2
3
4
5
6
7
8
#C++
上次更新: 2022/06/17, 07:22:19
shared_ptr(智能指针)
bind函数

← shared_ptr(智能指针) bind函数→

最近更新
01
HPE gen10 plus 安装ESXI 7
06-12
02
ESXI 7安装黑群晖
06-12
03
ESXI 7安装win10
06-12
更多文章>
Theme by Vdoing | Copyright © 2022-2024 ZhBing Zheng | 粤ICP备2022062743号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式