智能指针
当我们用两个指针指向同一个堆区空间时,会出现一个问题,那就是不能对同一个堆区空间delete两次。
为避免两个指针指向同一个堆区空间,有三种方法
1,深拷贝
2,建立所有权概念,也就是对于特定对象只能有一个智能指针可拥有它。
3,对特定对象进行引用计数,赋值时计数加一,指针过期时计数减一
仅当最后一个指针过期时,调用 delete。
unique_ptr :独占指针
独占指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr
//初始化
class Test;
unique_ptr<Test> ptr(new Test(3));
//赋值,所有权转移
unique_ptr<Test> ptr1 = move(ptr);
//重新赋值
ptr.reset(nullptr);
//获取原指针
Test* pt = ptr1.get();
//删除器指定
unique_ptr<Test , function<void(Test*)>> ptr4(new Test(1) [](Test*t))
{
cout<<"-------------------------"<<endl;
delete t;
}
share_ptr : 共享指针
shared_ptr的初始化:
共享智能指针是指多个智能指针可以同时管理同一块有效的内存,共享智能指针shared_ptr 是一个模板类,
如果要进行初始化有三种方式:通过构造函数、std::make_shared辅助函数以及reset方法。
共享智能指针对象初始化完毕之后就指向了要管理的那块堆内存,如果想要查看当前有多少个智能指针同时管理着这块内存可以使用共享智能指针提供的一个成员函数use_count
获取原始指针:
对应基础数据类型来说,通过操作智能指针和操作智能指针管理的内存效果是一样的,可以直接完成数据的读写。
但是如果共享智能指针管理的是一个对象,那么就需要取出原始内存的地址再操作,可以调用共享智能指针类提供的get()方法得到原始地址
指定删除器:
当智能指针管理的内存对应的引用计数变为0的时候,这块内存就会被智能指针析构掉了。
另外,我们在初始化智能指针的时候也可以自己指定删除动作,这个删除操作对应的函数被称之为删除器,这个删除器函数本质是一个回调函数,我们只需要进行实现,其调用是由智能指针完成的
//初始化
shared_ptr<Test> ptr1(new Test(6));
shared_ptr<Test> ptr2 = ptr1;
shared_ptr<Test> ptr3 = make_shared<Test>(10);
ptr3.reset(new Test(9));
//指针引用计数
cout<<ptr2.use_count()<<endl;
//获取原指针
Test* t = ptr3.get();
//如果是数组类型的地址,就需要自己写指定删除器,否则内存无法全部释放
//自定义删除器
shared_ptr<Test> ppp(new Test(100), [](Test* t) {
cout << "Test对象的内存被释放了......." << endl;
delete t;
});