27.C++- 智能指针
2018-06-17 20:50:49来源:未知 阅读 ()
智能指针
- 在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中的其它智能指针(在后面学习到,再来深入描述)
可以通过T *data()成员函数来获取指向的地址
-weak_ptr
- 配合shared_ptr而引入的一种智能指针
-unique_ptr
- 只能一个指针对象指向一片内存空间(和auto_ptr类似),但是不能被拷贝和赋值(实现唯一性)
QT中的智能指针
-QPointer
- 当其指向的对象被销毁时,本身会自动赋值为NULL(从而避免被多次释放和野指针)
- 缺点在于,该模板类析构时,不会自动摧毁所指向的对象(需要手工delete)
-QSharedPointer
- 带有引用计数机制,支持多个指针对象指向同一片内存(实现共享)
- 可以被自由地拷贝和赋值
- 当引用计数为0(最后一个指针被摧毁)时,才删除指向的对象(和shared_ptr类似)
-QScopedPointer
- 优点在于生命期结束后会自动删除它所指的对象(不需要手工delete)
- 不支持多个QScopedPointer指针对象指向同一片内存(不能共享)
示例:
QScopedPointer<QPushButton> p1(new QPushButton);
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- C++ this指针 2020-06-03
- 纯虚函数与基类指针数组的运用 代码参考 2020-04-30
- 成员指针与mem_fn 2020-04-23
- 第三章 类与对象进阶 2020-04-04
- C语言数组指针的理解方式 2020-03-31
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash