Zhonghui

每个不曾起舞的日子,都是对生命的辜负

User Tools

Site Tools


程序:cpp:智能指针

C++智能指针

学习实现的方式,是不是静态成员变量?

强指针:归属 / 弱指针:观察


这里指的智能指针有3种
3者都是从C++11开始提供支持
智能是相较于C风格的指针来说的

  • std::unique_ptr<T>
  • std::shared_ptr<T>
  • std::weak_ptr<T>
  • std::auto_ptr<T>已被废弃
#include<memory>

RAII:Resource acquisition is initialization(资源获取即初始化)
RAII要求,资源的有效期与持有资源的对象的生命期严格绑定,即由对象的构造函数完成资源的分配(获取),同时由析构函数完成资源的释放,在这种要求下,只要对象能正确地析构,就不会出现资源泄露问题

std::unique_ptr<T>

当我们独占资源的所有权的时候使用
可以使用get()获得普通指针,只要这个对象还没有被销毁,指针就可以安全使用
可以使用release()释放资源,可以使用reset()重设指针

//分配内存
std::unique_ptr<int> uptr = std::make_unique<int>(200);
//move-only 不能直接赋值(否则就会有多次析构)
//Error: std::unique_ptr<int> uptr_01 = uptr;
//Accepted: std::unique_ptr<int> uptr_02 = std::move(uptr);
//分配连续的内存块 参数是分配内存的大小
std::unique_ptr<int[]> uptr_array = std::make_unique<int[]>(10);

std::shared_ptr<T>

对资源做引用计数,当引用计数为0的时候,自动释放资源
可以使用get()获得普通指针,和unique类似,可以使用reset()重设指针
不能使用release()释放资源,多个对象指向相同的内存位置,不能由一个释放

//分配内存
std::shared_ptr<int> sptr = std::make_shared<int>(200);
//可以随意赋值 因为本就是共享的资源
std::shared_ptr<int> sptr_01 = sptr;

shared_ptr基本上就可以当成安全的指针来使用了,只需要管资源分配,不用处理资源释放,随便传递赋值

C++17新增了,使用shared_ptr管理数组的特性

// 负责创建一个元素类型为 int、大小为 10 的数组
// 但是这种方式只支持固定大小
auto myArray = std::make_shared<int[]>(10);
 
// 创建变长的数组
uint64_t bytes_size = static_cast<uint64_t>(width) * height * 3;
uint8_t* raw_ptr = new uint8_t[bytes_size];
this->data = std::shared_ptr<uint8_t[]>(raw_ptr, std::default_delete<uint8_t[]>());

std::weak_ptr<T>

std::weak_ptr要与std::shared_ptr一起使用
一个std::weak_ptr对象看做是std::shared_ptr对象管理的资源的观察者
但是它不影响std::shared_ptr的生命周期
如果需要使用weak_ptr正在观察的资源,可以将weak_ptr提升为shared_ptr
当shared_ptr管理的资源被释放时,weak_ptr会自动变成nullptr

其他

一个普通变量的指针(&some_thing),如何变为智能指针?
不要有这种想法,自动变量不会引起内存泄露,它们在生命周期结束时会自动被销毁,没有智能指针的说法

/var/www/DokuWikiStick/dokuwiki/data/pages/程序/cpp/智能指针.txt · Last modified: 2024/12/10 10:49 by zhonghui