C++智能指针 auto_ptr、shared_ptr、weak_ptr和unique_ptr
手写代码是理解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;//运行到[2]时崩溃,因为country[2]为空
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");
}
C++智能指针 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> ...
- C++智能指针(auto_ptr)详解
智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足 ...
随机推荐
- Ubuntu搜狗拼音输入法崩溃问题
Ubuntu 14.04.5 LTS 环境下搜狗拼音经常崩溃,似乎也没有什么特别好的解决办法. 以下是重启命令 #!/bin/sh >/dev/>& >/dev/>&a ...
- 跑步“无核心,不PB”
核心力量不管是在跑步中,还是在生活中都有着重要的作用,核心能让你的身体机能更加强劲. 1.什么是核心肌群? 核心肌群就是指我们所说的躯干,包括脊柱.骨盆.及周围肌群. 核心肌群由腹直肌.腹横肌.腹斜肌 ...
- conda 常用命令
conda search --full --name python conda update -n base conda //update最新版本的conda conda create -n xxxx ...
- java中判断是否是一个无用的类
类需要同时满足以下三个条件才能算是无用的类: 1.该类所有的实例都已经被回收,也就是java堆中不存在类的任何实例 2.加载该类的ClassLoader已经被回收 3.该类对应的java.lang.C ...
- Selenium+TestNG+Maven+Jenkins+SVN(转载)
转载自:https://blog.csdn.net/u014202301/article/details/72354069 一. 创建Maven项目,下载Selenium和TestNG的依赖(依赖可以 ...
- 2019 年 React 学习路线图(转)
转自:https://www.infoq.cn/article/AEkiVAiJf25LZmoUe_yc 之前我们已经介绍了2019 年 Vue 学习路线图,而 React 作为当前应用最广泛的前端框 ...
- Debian 8 安装Nginx最新版本
在Debian下如果直接apt-get install nginx直接装发现nginx版本是很旧的,本文主要讲一下如何在Debian 8上装新版的nginx. 原文资料:https://nginx.o ...
- 自定义Log 写到文件中
using System; using System.Collections.Generic; using System.Web; using System.IO; using System.Text ...
- Activity 启动模式 FLAG
原文:https://blog.csdn.net/youhongyan/article/details/64151922 一.Activity启动模式的设置在AndroidManifest.xml文件 ...
- 洛谷 P1426小鱼会有危险吗
题目: 有一次,小鱼要从A处沿直线往右边游,小鱼第一秒可以游7米,从第二秒开始每秒游的距离只有前一秒的98%.有个极其邪恶的猎人在距离A处右边s米的地方,安装了一个隐蔽的探测器,探测器左右x米之内是探 ...