C++智能指针知识总结(一)
最近学习了一下C++的智能指针,通过正确的使用,智能指针能让动态内存管理变得更简单。
new和delete
new和delete是传统的管理动态内存的方式,直接管理内存,其管理的内存在被delete显示释放之前一直存在,这里记录一些我自己较少见到的东西:
const int *p=new const int(1024); //动态分配常量,必须初始化
直接使用new和delete容易出现很多问题,常见的问题有三种:
忘记delete内存
使用已经释放的内存
同一内存释放两次
智能指针的种类
主要使用的有shared_ptr,unique_ptr,weak_ptr,这三种类型都定义在头文件memory中,不同的智能指针有不同的适用场景,这次我们来讨论shared_ptr,shared_ptr适用于用多个指针指向同一个内存块,在share_ptr中存在一种“引用计数”的方法,当shared_ptr的引用计数为0时,他便会将管理的内存自动释放掉。
shared_ptr的作用
我们可以认为每个shared_ptr都可以关联到某一个计数器,当多个智能指针共同管理一个内存时,可以认为他们被关联到同一个计数器上,当其中某一指针被拷贝,作为参数或返回值时,计数器递增,当某一指针被赋值或因离开作用域而销毁时,计数器递减,当计数器递减到0时,这块内存便被自动释放。例子如下:
auto p=make_shared<int>(42);
auto r=make_shared<int>(35);
r=q;//r所关联的计数器递减,q所关联的计数器递增,由于r所管理的原内存无其他关联的智能指针,引用计数变为0,原内存被释放
由于这个特性,我们必须保证,当一个shared_ptr不再使用时必须被销毁。
智能指针的声明
智能指针也是模板,声明例子如下:
shared_ptr<int> p1;
shared_ptr<vector<int>> p2;//还可指向容器
默认初始化的智能指针保存一个空指针。
支持的一些操作
智能指针都支持的操作
将智能指针作为一个判断条件,如:
if(p1)
{
//要执行的操作
}
若p1指向一个对象,则结果为true,否则为false。
p1.get();
获取智能指针p1中保存的指针,使用这个方法时要特别注意,具体细节稍后说明。
只有shared_ptr支持的操作
shared_ptr<T> p=make_shared<T>(argumemt); //返回一个用argument创建的智能指针
shared_ptr<T>p(q); //此操作将递增q的引用计数,递减p的引用计数
p.use_count(); //返回与p共享同一内存块的智能指针数量
p.unique(); //若一个内存块仅有该智能指针p管理,则返回true,否则返回false
操作详解
make_shared
最安全的分配动态内存的方式是使用make_shared函数。用法如下:
shared_ptr<int> p1=make_shared<int>(42);
auto p2=make_shared<vector<string>>();//更为常见的做法
shared_ptr和new结合使用
shared_ptr<int> p1(new int (1024));
shared_ptr<int> p1=new int(1024); //这是错误的,智能指针与普通指针不可隐式转换