C++智能指针 shared_ptr,unique_ptr和weak_ptr

1.智能指针为什么存在?

因为C++没有自动回收内存的机制,因此每一次new出来的动态内存必须手动delete回去。因此智能指针可以解决这个问题。

2.智能指针的大致描述是什么?

智能指针:自动负责释放所指向的对象,实际上它利用了栈的机制,每一个智能指针都是一个模板类,调用智能指针实际上是创建了一个智能指针的对象,对象生命周期到达尽头的时候,会自动调用智能指针的析构函数,在析构函数里,释放掉它管理的内存,从而避免手动delete。

3.三大类智能指针是什么?

指针 简要描述
shared_ptr 允许多个指针指向同一个对象
unique_ptr 独占所指向的对象
weak_ptr shared_ptr的弱引用

shared_ptr描述(in memory):

shared_ptr是一个标准的共享所有权的智能指针,就是允许多个指针指向同一对象,shared_ptr对象中不仅有一个指针指向某某(比如 int型,以下也拿int类型举例)对象,还拥有一个引用计数器,代表一共有多少指针指向了那个对象。

shared_ptr自动销毁所管理的对象

每当创建一个shared_ptr的对象指向int型数据,则引用计数器值+1,每当销毁一个shared_ptr对象,则-1.当引用计数器数据为0时,shared_ptr的析构函数会销毁int型对象,并释放它占用的内存。

shared_ptr和new的配合使用

接受指针作为参数的智能指针的构造函数是explicit类型,意味着只能以初始化的方式定义。
定义方法:

shared_ptr<int> p1;
//被初始化成为一个空指针

shared_ptr<int> p2 (new int(4));
//指向一个值是4的int类型数据

shared_ptr<int> p3 = new int(4);
//错误,必须直接初始化

不能混合使用普通指针和智能指针,因为智能指针不是单纯的赤裸裸的指针

void process(shared_ptr<int> ptr){
//受到参数值传递的影响,ptr被构造并且诞生,执行完函数块后被释放
}

int *x(new int (43));
//x是一个普通的指针

process(x);
//错误,int * 不能转换成shared_ptr类型

process(shared_ptr<int> x);
//临时创造了x,引用数+1,执行完process之后,引用数-1

int j = *x;
//x是一个空悬指针,是未定义的

不能使用get()函数对智能指针赋值或初始化

原因:get()函数得到的是共享对象的地址,是内置指针,指向智能指针管理的对象,而智能指针不仅仅包含地址,两个东西不是一个类型的,也不能彼此包含,因此不能这样做。
同样,把get()返回值 绑定到智能指针上也是错误的
如下:

shared_ptr<int> p (new int(22));
int *q = p.get();
//语义没问题

{
shared_ptr<int> (q);
//意味着q被绑定,!!!!引用计数器还是1!!!!
//如果这个被执行,程序块结束以后q和q所指的内容被销毁,则代表着以后执行(*p)的解引用操作,就成了未定义的了。
}

int r = *p;
//已经不对了,因为p指向的内存已经在刚才那个代码块里被q释放了

shared_ptr的一些操作

shared_ptr p;
//空智能指针,可指向类型是T的对象

if(p)
 //如果p指向一个对象,则是true

(*p)
//解引用获取指针所指向的对象

p -> number == (*p).number;

p.get();
//返回p中保存的指针

swap(p,q);
//交换p q指针

p.swap(q);
//交换p,q指针

make_shared(args) 
//返回一个shared_ptr的对象,指向一个动态类型分配为T的对象,用args初始化这个T对象

shared_ptr p(q)
//p 是q的拷贝,q的计数器++,这个的使用前提是q的类型能够转化成是T*

shared_pts p(q,d) 
//p是q的拷贝,p将用可调用对象d代替delete
//上面这个我其实没懂,也没有查出来这个的意思

p =q;
//p的引用计数-1,q的+1,p为零释放所管理的内存

p.unique();
//判断引用计数是否是1,是,返回true

p.use_count();
//返回和p共享对象的智能指针数量

p.reset();
p.reset(q);
p.reset(q,d);
//reset()没懂,这个以后再来补充吧

unique_ptr描述(in memory):

与shared_ptr不同,某一时刻,只能有一个unique_ptr指向一个给定的对象。因此,当unique_ptr被销毁,它所指的对象也会被销毁。

unique_ptr的初始化必须采用直接初始化

unique_ptr<string> p(new string("China"));
//没问题

unique_ptr<string> p (q);
//错误,不支持拷贝

unique_ptr<string> q;

q = p;
//错误,不支持赋值

unique_ptr的一些操作:

unique_ptr p;
//空智能指针,可指向类型是T的对象

if(p) 
//如果p指向一个对象,则是true

(*p)
//解引用获取指针所指向的对象

p -> number == (*p).number;

p.get();
//返回p中保存的指针

swap(p,q);
//交换p q指针

p.swap(q);
//交换p,q指针

unique_ptrp;
//p使用D类型的可调用对象释放它的指针

p = nullptr;
//释放对象,将p置空

p.release();
//p放弃对指针的控制,返回指针,p置数空

p.reset();
//释放p指向的对象

p.reset(q);
//让u指向内置指针q

unique_ptr作为返回值是可以的,这样可以拷贝或者赋值

weak_ptr描述(in memory)

weak_ptr是一种不控制所指向对象生存期的智能指针,指向shared_ptr管理的对象,但是不影响shared_ptr的引用计数。它像shared_ptr的助手,一旦最后一个shared_ptr被销毁,对象就被释放,weak_ptr不影响这个过程。

weak_ptr的一些操作:

weak_ptr<T> w(sp);
//定义一个和shared_ptr sp指向相同对象的weak_ptr w,T必须能转化成sp指向的类型

w = p;
//p是shared_ptr或者weak_ptr,w和p共享对象

w.reset();
//w置为空

w.use_count();
//计算与w共享对象的shared_ptr个数

w.expired();
//w.use_count()为0,返回true

w.lock();
//w.expired()为true,返回空shared_ptr,否则返回w指向对象的shared_ptr

你可能感兴趣的:(c/c++)