博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Smart Pointer 智能指针
阅读量:5275 次
发布时间:2019-06-14

本文共 3625 字,大约阅读时间需要 12 分钟。

P76

参考:http://www.cnblogs.com/lanxuezaipiao/p/4132096.html

  http://blog.csdn.net/hackbuteer1/article/details/7561235

简介

智能指针是存储指向动态分类(堆)对象的指针的类,用于生存期控制,确保在离开指针作用域时,自动正确销毁动态分配的对象。

通过引用计数的技术来实现,每使用它一次,内部的引用计数就加1,每析构一次,引用计数减1,减到0时就销毁对象,回收内存。

头文件 #include <memory>

分类

三种智能指针:

  • std::shared_ptr  实现共享式拥有,多个指针可以指向相同的对象,该对象和相关资源会在最后一个reference被销毁时释放
  • std::unique_ptr  实现独占式拥有,保证同一时间内只有一个指针可以指向该对象
  • std::weak_ptr    持有被shared_ptr所管理对象的引用,但是不会改变引用计数值。允许共享但不拥有某对象

另一方面,auto_ptr已经被废弃,C98,之前和std::unique_ptr一个意思

使用

1 #include 
2 #include
3 #include
4 5 class report 6 { 7 private: 8 std::string str; 9 public:10 report(const std::string s) : str(s) {11 std::cout << "Object created.\n";12 }13 ~report() {14 std::cout << "Object deleted.\n";15 }16 void comment() const {17 std::cout << str << "\n";18 }19 };20 21 int main() {22 {23 std::auto_ptr
ps(new report("using auto ptr"));24 ps->comment();25 }26 27 {28 std::shared_ptr
ps(new report("using shared ptr"));29 ps->comment();30 }31 32 {33 std::unique_ptr
ps(new report("using unique ptr"));34 ps->comment();35 }36 return 0;37 }

 

注意:智能指针的初始化必须使用复制初始化而不能采用赋值初始化,因为智能指针类的构造函数是explicit,只能够显示的调用构造函数

str_ptr
p1 = new string("hello") //error,赋值初始化隐式调用构造函数str_ptr
p2(new string("world")) //OK

 

unique_ptr注意拥有权必须用move

unique_ptr
p2(new string("hello")); unique_ptr
p3; p3 = std::move(p2);

p2失去拥有权不能在被调用了

unique_ptr比auto_ptr的好处在于如果p3 = p2,unique_ptr在编译时就能发现错误,auto_ptr要在运行时才能发现错误

shared_ptr实现

参考:http://www.jianshu.com/p/0300b2d833af

分析:

成员,一个模板指针T *p,一个引用计数的int *count;

成员函数:

构造函数:接受T *参数初始化成员p,初始化count为1,注意count需要new,p就不用了,p是在使用过程中new的

复制构造函数:注意形参不要用const类型,是引用类型的smart_point类,让count等于形参.count++,让p等于形参.p

析构函数:首先先对*count自减,不是0就算了,是0的话delete   p和count

然后写重载几个运算符*,->和=

*是返回T&类型,返回*p

->返回T*类型也就是指针,返回的是p

=首先将*count加一,然后为了防止自己=自己要判断count自减后是不是0,最后用对count和p进行赋值操作

1 #include 
2 #include
3 using namespace std; 4 5 template
6 class smart_ptrs { 7 8 public: 9 smart_ptrs(T*); //用普通指针初始化智能指针10 smart_ptrs(smart_ptrs&);11 12 T* operator->(); //自定义指针运算符13 T& operator*(); //自定义解引用运算符14 smart_ptrs& operator=(smart_ptrs&); //自定义赋值运算符15 16 ~smart_ptrs(); //自定义析构函数17 18 private:19 int *count; //引用计数20 T *p; //智能指针底层保管的指针21 };22 23 template
24 smart_ptrs
::smart_ptrs(T *p) : count(new int(1)), p(p) {25 cout << "创建对象" << *p << ",引用计数:" << *count << endl;26 }27 28 template
29 //对普通指针进行拷贝,同时引用计数器加1,因为需要对参数进行修改,所以没有将参数声明为const30 smart_ptrs
::smart_ptrs(smart_ptrs &sp) : count(&(++*sp.count)), p(sp.p) {31 cout << "调用复制构造函数,拷贝:" << *sp.p << ",引用计数:" << *count << endl;32 }33 34 template
35 T* smart_ptrs
::operator->() {36 return p;37 }38 39 template
40 T& smart_ptrs
::operator*() {41 return *p;42 }43 44 template
45 smart_ptrs
& smart_ptrs
::operator=(smart_ptrs& sp) {46 ++*sp.count;47 if (--*count == 0) { //自我赋值同样能保持正确48 delete count;49 delete p;50 }51 this->p = sp.p;52 this->count = sp.count;53 cout << "赋值操作," << *this->p << "引用计数变为" << *this->count << endl;54 return *this;55 }56 57 template
58 smart_ptrs
::~smart_ptrs() {59 if (--*count == 0) {60 delete count;61 delete p;62 }63 }64 65 int main()66 {67 smart_ptrs
pstr(new string("abc"));68 smart_ptrs
pstr2(pstr);69 smart_ptrs
pstr3(new string("bcd"));70 pstr3 = pstr2;71 72 system("pause");73 }

 

转载于:https://www.cnblogs.com/raichen/p/5697235.html

你可能感兴趣的文章
51nod1307(暴力树剖/二分&dfs/并查集)
查看>>
用户体验分析: 以 “南通市图书馆微信公众号” 为例
查看>>
linux的管道 |和grep命令以及一些其他命令(diff,echo,cat,date,time,wc,which,whereis,gzip,zcat,unzip,sort)...
查看>>
Nginx和PHP-FPM的启动、重启、停止脚本分享
查看>>
cookie 和session 的区别详解
查看>>
Vuex-状态管理模式
查看>>
浮点数运算的精度问题:以js语言为例
查看>>
数据挖掘领域十大经典算法
查看>>
【C语言】09-字符串
查看>>
数据库连接及线程池
查看>>
解决android应用程序适用新老android系统版本方法
查看>>
Oracle SQL语句执行过程
查看>>
Oracle 中的SID是什么意思?有什么作用?
查看>>
关于http协议
查看>>
jquery validation remote进行唯一性验证时只使用自定义参数,不使用默认参数
查看>>
软件工程个人项目——买书的最低价格
查看>>
5-21
查看>>
springboot 集成 swagger 自动生成API文档
查看>>
Oracle 分类统计sql
查看>>
HDU-2476 String painter 区间DP
查看>>