聊聊智能指针 auto_ptr、shared_ptr、weak_ptr和unique_ptr
本文为转载:https://www.cnblogs.com/zeppelin5/p/10083597.html,对作者有些地方做了修正。
手写代码是理解C++的最好办法,以几个例子说明C++四个智能指针的用法,转载请注明出处。
一、auto_ptr
auto_ptr这是C++98标准下的智能指针,现在常常已经被C++标准的其他智能指针取代。它的缺点是在转移所有权后会使运行期不安全。C++11新标准,用unique_ptr来代替auto_ptr原有功能,其用法介绍见第四部分unique_ptr。
#include <iostream>
#include <memory>
#include <string>
using namespace std; void main(){
auto_ptr<string> country[] =
{
auto_ptr<string>(new string("USA")),
auto_ptr<string>(new string("CHN")),
auto_ptr<string>(new string("RUS")),
auto_ptr<string>(new string("FRA")),
auto_ptr<string>(new string("GRB"))
}; auto_ptr<string> pwin;
pwin = country[]; //将所有权从country[2]转让给pwin,此时country[2]不再引用该字符串从而变成空指针,在运行到循环时就会崩溃 for (int i = ; i < ; ++i)
cout << *country[i] << endl;//运行到[2]时崩溃,因为country[2]为空
cout << "The best is " << *pwin << endl; system("pause");
}
二、share_ptr
share_ptr是C++11新添加的智能指针,它限定的资源可以被多个指针共享。
用法见下例:
#include <iostream>
#include <memory>
#include <string>
using namespace std; void fun(){
shared_ptr<string> pa(new string("CHN"));
shared_ptr<string> pb(new string("USA"));
cout << "*pa " << *pa << endl;//CHN
cout << "pa.use_count " << pa.use_count() << endl;//
cout << "*pb " << *pb << endl;//USA
cout << "pb.use_count " << pb.use_count() << endl;// pa = pb;
cout << *pa << endl;//USA
cout << "pa.use_count " << pa.use_count() << endl;//2:pa和pb指向同一个资源USA了,该资源的计数为2,所以pb、pb都输出2
cout << "pb.use_count " << pb.use_count() << endl;// pa.reset();
pb.reset();
cout << "pa.use_count " << pa.use_count() << endl;//
cout << "pb.use_count " << pb.use_count() << endl;//
} void main()
{
fun();
system("pause");
}
与数组相结合应用,见另一个例子:
#include <iostream>
#include <memory>
#include <string>
using namespace std; void main(){
shared_ptr<string> country[] =
{
shared_ptr<string>(new string("USA")),
shared_ptr<string>(new string("CHN")),
shared_ptr<string>(new string("RUS")),
shared_ptr<string>(new string("FRA")),
shared_ptr<string>(new string("GRB"))
}; shared_ptr<string> pwin;
cout << pwin.use_count() << endl;//输出0
pwin = country[];
/*使用shared_ptr时运行正常,因为shared_ptr采用引用计数,pwin和films[2]都指向同一块内存,
在释放空间时因为事先要判断引用计数值的大小因此不会出现多次删除一个对象的错误。 从名字share就可以看出了资源可以被多个指针共享,它使用计数机制来表明资源被几个指针共享。
可以通过成员函数use_count()来查看资源的所有者个数。
*/
cout << pwin.use_count() << endl;//输出2 for (int i = ; i < ; ++i)
cout << *country[i] << endl;//对比auto_ptr,这里就不会崩溃,正常的输出所有的string字符串。
cout << "The best is " << *pwin << endl; system("pause");
}
三、weak_ptr
weak_ptr是一种用于解决shared_ptr相互引用时产生死锁问题的智能指针。如果有两个shared_ptr相互引用,那么这两个shared_ptr指针的引用计数永远不会下降为0,资源永远不会释放。weak_ptr是对对象的一种弱引用,它不会增加对象的use_count,weak_ptr和shared_ptr可以相互转化,shared_ptr可以直接赋值给weak_ptr,weak_ptr也可以通过调用lock函数来获得shared_ptr。
先看一下两个shared_ptr指针互相引用导致的资源释放失败的例子:
#include <iostream>
#include <memory>
#include <string>
using namespace std; class B;
class A
{
public:
shared_ptr<B> pb_;
~A()
{
cout << "A delete\n";
}
};
class B
{
public:
shared_ptr<A> pa_;
~B()
{
cout << "B delete\n";
}
}; void fun(){
shared_ptr<B> pb(new B());
cout << "pb.use_count " << pb.use_count() << endl;//
shared_ptr<A> pa(new A());
cout << "pa.use_count " << pa.use_count() << endl;// pb->pa_ = pa;
cout << "pb.use_count " << pb.use_count() << endl;//
cout << "pa.use_count " << pa.use_count() << endl;//
pa->pb_ = pb;
cout << "pb.use_count " << pb.use_count() << endl;//2:由于share_ptr是共享资源,所以pb所指向的资源的引用计数也会加1
cout << "pa.use_count " << pa.use_count() << endl;//
}//程序结束时,没有调用A和B的析构函数 void main()
{
fun();
system("pause");
}
而使用weak_ptr:把A中的shared_ptr<B> pb_改为weak_ptr<B> pb_weak,这样改为了弱引用,传递时不会增加pb引用计数use_count()的值,所以最终能够使A、B资源正常释放:
#include <iostream>
#include <memory>
#include <string>
using namespace std; class B;
class A
{
public:
weak_ptr<B> pb_weak;
~A()
{
cout << "A delete\n";
}
};
class B
{
public:
shared_ptr<A> pa_;
~B()
{
cout << "B delete\n";
}
void print(){
cout << "This is B" << endl;
}
}; void fun(){
shared_ptr<B> pb(new B());
cout << "pb.use_count " << pb.use_count() << endl;//
shared_ptr<A> pa(new A());
cout << "pa.use_count " << pa.use_count() << endl;// pb->pa_ = pa;
cout << "pb.use_count " << pb.use_count() << endl;//
cout << "pa.use_count " << pa.use_count() << endl;// pa->pb_weak = pb;
cout << "pb.use_count " << pb.use_count() << endl;//1:弱引用不会增加所指资源的引用计数use_count()的值
cout << "pa.use_count " << pa.use_count() << endl;// shared_ptr<B> p = pa->pb_weak.lock();
p->print();//不能通过weak_ptr直接访问对象的方法,须先转化为shared_ptr
cout << "pb.use_count " << pb.use_count() << endl;//
cout << "pa.use_count " << pa.use_count() << endl;//
}//函数结束时,正确的情况下,应该调用A和B的析构函数 /*资源B的引用计数一直就只有1,当pb析构时,B的计数减一,变为0,B得到释放,
B释放的同时也会使A的计数减一,同时pa自己析构时也会使资源A的计数减一,那么A的计数为0,A得到释放。
*/ void main()
{
fun();
system("pause");
}
四、unique_ptr
unique_ptr 是一个独享所有权的智能指针,它提供了严格意义上的所有权。它取代了C++98中的auto_ptr。
用法和auto_ptr类似,详情见一下代码:
#include <iostream>
#include <memory>
#include <string>
using namespace std; unique_ptr<string> fun2(){
return unique_ptr<string>(new string("RUS"));
} void fun(){
unique_ptr<string> pa(new string("CHN"));
//unique_ptr没有use_count()方法
unique_ptr<string> pb(new string("USA")); pb = move(pa);
//p2=p1;//错误,不能直接用等于号
if (pa == nullptr)
cout << "pa现在为空" << endl; cout << "*pb " << *pb << endl;//pb变成了“CHA” string* ps = pb.release();//清空当前智能指针所指的资源对象,并返回指针
cout << "*ps " << *ps << endl;//ps变成了“CHA” pa.reset(ps);//重置指向另一个对象
cout << "*pa " << *pa << endl;//pa变成了“CHA” pb = fun2();//接收函数的返回值可以用等于号,因为使用了移动构造函数
cout << "*pb " << *pb << endl;//pb变成了“RUS”
} void main()
{
fun();
system("pause");
}
聊聊智能指针 auto_ptr、shared_ptr、weak_ptr和unique_ptr的更多相关文章
- 智能指针auto_ptr & shared_ptr
转载:智能指针auto_ptr 很多人听说过标准auto_ptr智能指针机制,但并不是每个人都天天使用它.这真是个遗憾,因为auto_ptr优雅地解决了C++设计和编码中常见的问题,正确地使用它可以生 ...
- C++智能指针: auto_ptr, shared_ptr, unique_ptr, weak_ptr
本文参考C++智能指针简单剖析 内存泄露 我们知道一个对象(变量)的生命周期结束的时候, 会自动释放掉其占用的内存(例如局部变量在包含它的第一个括号结束的时候自动释放掉内存) int main () ...
- C++ 智能指针(shared_ptr/weak_ptr)原理分析
其主要的类关系如下所示(省略相关的类模板参数): 图1 从上面的类图可以清楚的看出shared_ptr内部含有一个指向被管理对象(managed object)T的指针以及一个__shared_cou ...
- C++ | 再探智能指针(shared_ptr 与 weak_ptr)
上篇博客我们模拟实现了 auto_ptr 智能指针,可我们说 auto_ptr 是一种有缺陷的智能指针,并且在C++11中就已经被摈弃掉了.那么本章我们就来探索 boost库和C++11中的智能指针以 ...
- 【C++11新特性】 C++11智能指针之shared_ptr
C++中的智能指针首先出现在“准”标准库boost中.随着使用的人越来越多,为了让开发人员更方便.更安全的使用动态内存,C++11也引入了智能指针来管理动态对象.在新标准中,主要提供了shared_p ...
- C++智能指针之shared_ptr与右值引用(详细)
1. 介绍 在 C++ 中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露.解决这个问题最有效的方法是使用智能指针(smart pointer).智能指针是存储指向动态分配(堆)对象指针 ...
- 关于智能指针auto_ptr
智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个 感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解. 本篇主要介绍auto_ptr 其 ...
- 【C++智能指针 auto_ptr】
<More Effective C++>ITEM M9他提到auto_ptr.说是当异常产生的时候.怎么释放为对象分配的堆内存,避免反复编写内存释放语句. PS:这里书里面提到函数退出问题 ...
- 智能指针之shared_ptr基本概述
1.shared_ptr允许有多个指针指向同一个对象,unique_ptr独占所指向的对象. 2.类似于vector,智能指针也是模板.创建智能指针: shared_ptr<string> ...
随机推荐
- Mario是一个基于.NETCore的简单快速开发框架
Mario .NET Core简单快速开发框架 Mario是一个基于.NET Core的简单快速开发框架 GitHub:https://github.com/deeround/Mario 技术特点 基 ...
- Go语言实现:【剑指offer】两个链表的第一个公共结点
该题目来源于牛客网<剑指offer>专题. 输入两个链表,找出它们的第一个公共结点. Go语言实现: //长度长的先走个长度差,然后ab一起比较后面结点 //长度一样,公共结点可能在首结点 ...
- 微信小程序面试题总结
A类问题 1 请谈谈微信小程序主要目录和文件的作用? project.config.json 项目配置文件,用得最多的就是配置是否开启https校验: App.js 设置一些全局的基础数据等: App ...
- NR / 5G - The Round Robin algorithm
- Unable to update index for nexus-publish | http://ip:port/repository/maven-public/
问题描述:Unable to update index for nexus-publish | http://ip:port/repository/maven-public/ 解决方案:进入工作空间. ...
- Axer-使用Msfvenom自动创建有效负载的工具
Axer-使用Msfvenom自动创建有效负载的工具 该axer将替换为有效的手动操作msfvenom,设置更容易和快了很多. AXER可以让您选择平台,格式,编码器,与另一个文件绑定以及许多其他功能 ...
- 【转载】wav文件格式分析与详解
WAV文件是在PC机平台上很常见的.最经典的多媒体音频文件,最早于1991年8月出现在Windows 3.1操作系统上,文件扩展名为WAV,是WaveFom的简写,也称为波形文件,可直接存储声音波形, ...
- 数组翻转(非reverse)
var arr = [1,2,3,4]; var arr2 = []; while(arr.length) { var num = arr.pop(); //删除数组最后一个元素并返回被删除的元素 a ...
- [Contract] Solidity address payable 转换与数组地址
address payable --> address address payable addr1 = msg.sender; address addr2 = addr1; // 隐式转 a ...
- 在webform中使用ajax
如果你用过Asp.net webform, 说明你也算是.NET 开发的老兵了.WEBform应该是2011-2013左右,当时还用visual studio 2005. visual studio ...