C++语言- 智能指针
小标 2018-07-25 来源 : 阅读 966 评论 0

摘要:本文主要向大家介绍了C++语言- 智能指针,通过具体的内容向大家展示,希望对大家学习C++语言有所帮助。

本文主要向大家介绍了C++语言- 智能指针,通过具体的内容向大家展示,希望对大家学习C++语言有所帮助。

智能指针

· 在C++库中最重要的类模板之一

· 智能指针实际上是将指针封装在一个类里,通过对象来管理指针.

 

STL中的智能指针auto_ptr

头文件: <memory>

· 生命周期结束时,自动摧毁指向的内存空间

· 不能指向堆数组(因为auto_ptr的析构函数删除指针用的是delete,而不是delete[])

· auto_ptr的构造函数为explicit类型,所以只能显示初始化,比如:

 

  auto_ptr<int> ap1(new int(1));      //初始化正确,创建ap1类模板对象,使类模板里的指针为int*型,并指向1的地址

 

  int* p = new int(1);

  auto_ptr<int> ap2(p);               //初始化正确

 

 

  // auto_ptr<int> ap3 = new int(2);  //出错,不能隐式初始化

 

· 提供get()成员函数,可以用来查看类里的指针地址.比如:

  auto_ptr<int> ap(new int(1));         

  cout<< ap.get()<<endl;          //打印数值1的地址 : 0x6d2d18

      

  int *p =ap.get();

  cout<< *p<<endl;                  //打印数值1

· 一片堆空间只属于一个智能指针对象(因为多个指向相同地址的智能指针调用析构函数时,会出现bug)

· 当auto_ptr被拷贝或赋值后,则自身的指针指向的地址会被抢占,比如:

 

  auto_ptr<int> p1(new int(1));

  auto_ptr<int> p2(new int(2));

 

  p1 =p2;                                    //首先会delete p1对象的类成员指针,然后将p2对象的类成员指针赋值给p1, 最后修改p2指针地址为NULL

  cout<<"p2 ="<<p2.get()<<endl;             //打印 : p2=0

 

  //cout<<*p2<<endl;                        //出错,因为p2=0

 

 

初探auto_ptr智能指针

 

#include <iostream>

#include <memory>

using namespace std;

class Test

{public:

       int mvalue;

       Test(int i=0)

       {

              mvalue=i;

              cout<< "Test("<<mvalue<<")"<<endl;

       }

       ~Test()

       {

              cout<< "~Test("<<mvalue<<")"<<endl;

       }

};

void func()                           //在func函数里使用auto_ptr

{

       auto_ptr<Test> p1(new Test(1));

       cout<<"p1 ="<<p1.get()<<endl;

 

       cout<<endl;

 

       auto_ptr<Test> p2(new Test(2));

       cout<<"p2 ="<<p2.get()<<endl;

 

       cout<<endl;

 

       cout<<"p1=p2"<<endl;

       p1=p2;   

 

       cout<<endl;

 

       cout<<"p1 ="<<p1.get()<<endl;

       cout<<"p2 ="<<p2.get()<<endl;

}

int main()

{  

       cout<<"*****begin*****"<<endl;

       func();  

       cout<<"*****end*****"<<endl;

 

       return 0;

}

 

运行打印:

 

*****begin*****

Test(1)

p1 =0x8db1008

 

Test(2)

p2 =0x8db1018

 

p1=p2~Test(1)

 

p1 =0x8db1018

p2 =0

~Test(2)*****end*****

 

从结果可以看到,由于func()的生命周期结束,所以里面的auto_ptr指针自动就被释放了。

可以发现在调用p1=p2时, 首先会delete p1对象的类成员指针(调用~Test(1)析构函数),然后将p2对象的类成员指针赋值给p1(p1=0x8db1018), 最后修改p2指针地址为NULL(p2 =0)。

 

STL中的智能指针shared_ptr(需要C++11支持)

· 带有引用计数机制,支持多个指针对象指向同一片内存(实现共享)

· 提供swap()成员函数,用来交换两个相同类型的对象,比如:

 

  shared_ptr<int> p1(new int(1));

  shared_ptr<int> p2(new int(2));

 

  p1.swap(p2);                  //交换后 p1=2,p2=1

  cout<< *p1 <<endl;            //打印 2

  cout<< *p2 <<endl;            //打印 1

 

 

· 提供unique()成员函数, 判断该指针对象地址是否被其它指针对象引用

· 提供get()成员函数,用来获取指针对象指向的地址

· 提供reset()成员函数,将自身指针对象地址设为NULL,并将引用计数-1(当计数为0,会自动去delete内存)

· 提供use_count()成员函数,可以用来查看引用计数个数,比如:

 

  shared_ptr<int> sp1(new int(30));      //计数+1

  cout<<sp1.use_count()<<endl;           //打印计数:1

  cout<<sp1.unique()<<endl;              //打印:1

  

 

  shared_ptr<int> sp2(sp1);               //计数+1

  cout<<sp1.use_count()<<endl;            //打印:2

  cout<<sp1.unique()<<endl;               //由于sp1指针对象被sp2引用,打印:0

 

  sp1.reset();                            //将sp1指针对象地址设为NULL,计数-1

  cout<<sp1.get()<<endl;                  //sp1指针对象地址为NULL,打印:0

 

  cout<<sp2.use_count()<<endl;            //打印:1

  cout<<sp2.unique()<<endl;               //由于sp1释放,仅剩下sp2指向30所在的地址,所以打印:1

 

 

初探shared_ptr智能指针(以上个Test类为例分析)

 

#include <iostream>

#include <memory>

using namespace std;

class Test

{public:

       int mvalue;

       Test(int i=0)

       {

              mvalue=i;

              cout<< "Test("<<mvalue<<")"<<endl;

       }

 

       ~Test()

       {

              cout<< "~Test("<<mvalue<<")"<<endl;

       }

};

int main()

{  

       cout<<"*****begin*****"<<endl;

 

       shared_ptr<Test> p1(new Test(1));

       shared_ptr<Test> p2(p1);

 

       cout<<"*p1="<< p1->mvalue<<","<<"*p2="<<p2->mvalue<<endl;

 

       p1.reset();

       p2.reset();     

 

       cout<<"count:"<<p2.use_count()<<endl;

 

       cout<<"*****end*****"<<endl;

       return 0;

}

 

运行打印:

*****begin*****

Test(1)*p1=1, *p2=1

~Test(1)

count:0

*****end*****

从结果可以看到,我们把p1和p2都释放了后,由于count=0,便自动去delete Test指针了.

 

STL中的其它智能指针(在后面学习到,再来深入描述)

-weak_ptr

· 配合shared_ptr而引入的一种智能指针

-unique_ptr

· 只能一个指针对象指向一片内存空间(和auto_ptr类似),但是不能被拷贝和赋值(实现唯一性)

 

QT中的智能指针(在后面学习到,再来深入描述)

-QPointer

头文件<QPointer>

· 当其指向的对象被销毁时,他会被自动置空(避免被多次释放和野指针)

· 缺点在于,该模板类析构时,不会自动摧毁所指向的对象(需要手工delete)

-QSharedPointer

头文件<QSharedPointer>

· 带有引用计数机制,支持多个指针对象指向同一片内存(实现共享)

· 可以被自由地拷贝和赋值

· 当引用计数为0(最后一个指针被摧毁)时,才删除指向的对象(和shared_ptr类似)

本文由职坐标整理并发布,了解更多内容,请关注职坐标编程语言C/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程