智能指针使用方法简要总结,方便快速查询使用。
1.share_ptr
(1)允许多个指针指向同一个对象。
(2)支持的操作
share_ptr sp;//定义空智能指针
p将p当做条件判断,若指向对象,则为真
*p 解引用获取对象
p->m访问指针成员
p.get() 返回p中保存的指针,如果对象被智能指针释放,返回指针指向对象为空。
swap(p,q) 或p.swap(q)交换p和q的指针
share_ptr独有操作
make_shared(a) 返回一个share_ptr,并用a初始化
share_ptr p(q) p为q的拷贝,该操作增加q计数
share_ptr p(q,d) p为q的拷贝,该操作增加q计数,调用对象d代替delete函数
p=q 两个指针都是share_ptr,该操作增加q计数,减少p计数
p.unique() p引用计数为1返回true,否则返回false
p.sue_count() 返回p的引用计数,可能很慢主要用于调试
p.reset() 若p是唯一指向对象的shared_ptr,reset会释放该对象,p被置空。
p.reset(q) 在前一条基础上将p指向q。
p.reset(q,d) 在前一条基础上将p指向q,调用对象d代替delete函数。
示例:
share_ptr sp = make_shared(100);//创建一个指向100整型的智能指针
auto q(sp);//q指向sp对象,sp引用计数+1
(3)引用计数规则
拷贝share_ptr引用+1
初始化另一个share_ptr或者作为函数返回值也会+1
share_ptr被赋值或被销毁(离开作用域等)引用-1
如果计数为0析构函数会销毁share_p指向对象。
eg: share_ptr p = make_shared(50);
q= p; //q指向新地址,sp计数减1
(4)注意事项:
不要混合使用智能指针和普通指针:
int *x(new int(100));
process(shared_ptr(x));//x作为智能指针参数内部处理,函数返回时智能指针离开作用域,引用计数为0
int j = *x; //x指向对象已经在process函数中被智能指针释放,x是无效指针
不要使用get初始化或者赋值另一个智能指针,可能出现一个智能指针释放,另一个指针仍在使用,或者指针被释放两次。
2.unique_ptr
独占指向的对象,同一个时刻只能有一个unique_ptr指向给定对象,因此它不支持普通的拷贝或者赋值操作。
unique_ptr sp;//定义空智能指针
p将p当做条件判断,若指向对象,则为真
*p 解引用获取对象
p->m访问指针成员
p.get() 返回p中保存的指针,如果对象被智能指针释放,返回指针指向对象为空。
swap(p,q) 或p.swap(q)交换p和q的指针
unique_ptr独有操作:
unique_ptr<T,d> u()空的unique_ptr指针
unique_ptr<T,d> u(d)空的unique_ptr指针,调用对象d代替delete函数
u= nullptr 释放u指向对象,将u置空
u.release() 放弃u对指针控制权,返回指针并将u置空
u.reset() 释放u指向对象
u.reset(q) 释放u指向对象,如果提供了内置指针q,令u指向该对象
eg: unique_ptr p2(p1.release());//将p1置空,所有权交给p2
p2.reset(p3.release());//将p2内存释放,p3所有权交给p2
3.Weak_ptr
share_ptr伴随类,弱引用指向share_ptr管理的对象,不改变share_ptr引用计数。
unique_ptr sp;//定义空智能指针
unique_ptr sp(q);//和shared_ptr指向相同对象的weak_ptr
w=p //p可以是shared_ptr或者weak_ptr,指向同一个对象
w.reset() //置空
w.use_count() //关联的shared_ptr的引用计数
w.expired()//如果use_count()为0返回true,否则false
w.lock()//如果expired()为true,返回空shared_ptr,否则返回指向w对象的shared_ptr
4.自定义删除器:
#include<iostream>
#include<memory>
#include <functional>
using namespace std;
struct Data
{
public:Data(){pBuffer = new char[10];cout << "malloc pBuffer" << endl;};~Data(){};char* pBuffer;
};
void DeleteData(Data* p)
{if(p){delete [] p->pBuffer;cout << "delete pBuffer,"<<__FUNCTION__ << endl;}
}int main()
{shared_ptr<Data> pData(new Data(),DeleteData); //普通函数方式shared_ptr<Data> pData1(new Data(),[](Data* p) { //lamda表达式方式实现delete [] p->pBuffer;cout << "delete [] pBuffer pdata1," <<__FUNCTION__ << endl;});return 0;
}