C++——智能指针(shared_ptr、unique_ptr、weak_ptr)

智能指针:

是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针;

行为类似于常规指针,更容易也更安全的使用动态内存,负责自动释放所指向的对象;

智能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放;

三种智能指针:shared_ptr、unique_ptr、weak_ptr,均定义在memory头文件中。

1、shared_ptr

定义:

shared_ptr允许多个对象指向同一个对象,是一个标准的共享所有权的智能指针,C++11引入到C++ STL

用法:

shared_ptr<string> p1; //一个指向string类型的shared_ptr指针p1
shared_ptr<list<int>> p2;// 一个指向int型list的shared_ptr指针p2

默认初始化的只能指针中保存着一个空指针,解引用一个智能指针返回它所指向的对象

操作:

make_shared<T> (args)   返回一个shared_ptr,指向一个动态分配的类型为T的对象,用args初始化此对象
shared_ptr<T> p(q)      p是shared_ptr q的拷贝;该操作会递增q中的计数器,q中的指针必须能转化为T*
p=q                     p和q都是shared_ptr,所保存的指针能够相互转化;该操作递增q的引用计数,递减P的引用计数 
p.unique()              若p.use_count()为1,返回true,否则返回false
p.use_count()           返回和p共享对象的智能指针数量(主要用于调试)
p.get()                 返回p中保存的指针(返回一个内置指针,指向智能指针管理的对象 int *q=p.get())
swap(p,q)/p.swap(q)     交换p,q中的指针
p                       用作一个条件判断,若指向一个对象,最为true
*p                      解引用,获得它所指对象
p->mem                  等价于(*p).mem,获取所指对象成员

make_shared函数:

在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr,使用该函数时,必须指定想要创建的对象类型

shared_ptr<int> p3=make_shared<int>(42) 指向一个值为42的int
shared_ptr<string> p4=make_shared<string>(5,'b') 指向一个值为'bbbbb'的string的shared_ptr
shared_ptr<int> p5=make_shared<int>() 指向一个值初始化的int,值为0

通常用auto定义一个对象来保存make_shared的结果

//p6指向一个动态分配的空vector<string>
auto p6=make_shared<vector<string>>();

拷贝与赋值:

进行拷贝与赋值时,每个shared_ptr都会记录有多少的其他shared_ptr指向相同对象;

每一个shared_ptr都有一个关联计数器,叫做引用计数,拷贝时,计数器递增;

一个shared_ptr被赋予新值(改变指向对象,即不指向当前对象时)或被销毁时,计数器递减,减为0时自动释放所管理的对象。

auto r=make_shared<int>(42);
r=q;//给r赋值,令它指向q所指的地址
    //递增q指向对象的引用计数
    //递减r原来所指对象(42)的引用计数
    //r原来指向的对象没有引用者会自动释放

shared_ptr的析构函数会递减他所指对象的引用计数,变为0时会销毁对象,释放它所占的内存

ps:使用动态内存的原因

     1、程序不知道自己需要使用多少对象

     2、程序不知道所需对象的准确类型

     3、程序需要在多个对象间共享数据

2、unique_str

定义:

C++11引入,替代不安全的auto_ptr,一个unique_str"拥有"它所指的对象,持有对对象的独有权。

特点:

两个unique_ptr 不能指向一个对象,即 unique_ptr 不共享它所管理的对象;

只能移动unique_ptr,即对资源管理权限可以实现转移,意味着内存资源所有权可以转移到另一个 unique_ptr,并且原始    unique_ptr 不再拥有此资源;

运行效率高,因为通过 unique_ptr 的移动构造函数,不再需要进行复制操作;

与所指对象的关系:

在智能指针生命周期内,可以改变智能指针所指对象,如创建智能指针时通过构造函数指定、通过 reset 方法重新指定、通过 release 方法释放所有权、通过移动语义转移所有权,unique_ptr 还可能没有对象,这种情况被称为 empty。

操作:

//智能指针的创建
unique_ptr<int> u_i; 	//创建空智能指针
u_i.reset(new int(3)); 	//绑定动态对象  
unique_ptr<int> u_i2(new int(4));//创建时指定动态对象
unique_ptr<T,D> u(d);	//创建空 unique_ptr,执行类型为 T 的对象,用类型为 D 的对象 d 来替代默认的删除器 delete

//所有权的变化   
unique_ptr<string> u_s(new string("abc"));  
unique_ptr<string> u_s2 = std::move(u_s); //所有权转移(通过移动语义),u_s所有权转移后,变成“空指针” 
u_s2.reset(u_s.release());	//所有权转移
u_s2=nullptr;//显式销毁所指对象,同时智能指针变为空指针。与u_s2.reset()等价
u.release();     //放弃控制权,返回指针,u置空  int *p_i = u_i2.release();	 
u.reset();      //释放u所指对象
u.reset(q)      //如果提供内置指针q,u指向q,否则置空
u.reser(nullptr)

3、weak_ptr

定义:

一种不控制所指对象生命周期的智能指针,它指向由一个shared_ptr管理的对象。

weak_ptr 是为了配合 shared_ptr 而引入的一种智能指针,它更像是 shared_ptr 的一个助手而不是智能指针,因为它不具有普通指针的行为,没有重载 operator* 和 operator-> ,因此取名为 weak,表明其是功能较弱的智能指针。

weak_ptr 只对 shared_ptr 进行引用,而不改变其引用计数,当被观察的 shared_ptr 失效后,相应的 weak_ptr 也相应失效。

操作:

weak_ptr<T> w;	 	//创建空 weak_ptr,可以指向类型为 T 的对象
weak_ptr<T> w(sp);	//与 shared_ptr 指向相同的对象,shared_ptr 引用计数不变。T必须能转换为 sp 指向的类型
w=p;				//p 可以是 shared_ptr 或 weak_ptr,赋值后 w 与 p 共享对象
w.reset();			//将 w 置空
w.use_count();		//返回与 w 共享对象的 shared_ptr 的数量
w.expired();		//若 w.use_count() 为 0,返回 true,否则返回 false
w.lock();			//如果 expired() 为 true,返回一个空 shared_ptr,否则返回非空 shared_ptr

使用 weak_ptr 的成员函数 use_count() 可以观测资源的引用计数,另一个成员函数 expired() 的功能等价于 use_count()==0,但更快,表示被观测的资源(也就是 shared_ptr 管理的资源)已经不复存在。weak_ptr 可以使用一个非常重要的成员函数lock()从被观测的 shared_ptr 获得一个可用的 shared_ptr 管理的对象, 从而操作资源。但当 expired()==true 的时候,lock() 函数将返回一个存储空指针的 shared_ptr。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
shared_ptrC++中的智能指针,它采用引用计数的方法来实现释放指针所指向的资源。当使用shared_ptr时,它会记录有多少个shared_ptr指向同一个对象,只有当最后一个shared_ptr被销毁时,该对象的内存才会被释放。因此,shared_ptr可以自动管理内存,不需要手动释放。 在代码中,使用shared_ptr可以像普通指针一样操作对象。当需要创建一个shared_ptr对象时,可以使用std::make_shared函数来构造,如下所示: ``` std::shared_ptr<int> sharedPtr1 = std::make_shared<int>(10); ``` 可以通过将shared_ptr赋值给其他shared_ptr来共享资源,如下所示: ``` std::shared_ptr<int> sharedPtr2 = sharedPtr1; ``` 当所有的shared_ptr都被销毁时,内存会自动释放。可以使用use_count()函数获取shared_ptr的引用计数,如下所示: ``` std::cout << "sharedPtr2 use count: " << sharedPtr2.use_count() << std::endl; ``` 当引用计数为0时,内存会被自动释放。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++智能指针shared_ptr分析](https://download.csdn.net/download/weixin_38705004/13788082)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C++11中的智能指针unique_ptrshared_ptrweak_ptr详解](https://blog.csdn.net/chenlycly/article/details/130918547)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值