C++ Primer第十二章④

C++ Primer

更多内容戳这里

动态内存

我们讲了那么多,只是讲了三个智能指针中的一个shared_ptr,还有两个呢:unique_ptr和weak_ptr(是不是很烦)学好了第一个,那后面两个其实也还算简单,下面我们分别来介绍。

unique_ptr

一个unique_ptr独有它所指向的对象,与shared_ptr(人尽可夫)不同,unique_ptr比较霸道总裁,某个时刻只能有一个unique_ptr指向给定的对象,所以啊,当unique_ptr被销毁时,它所指向的对象也被销毁。

unique_ptr p1;
unique_ptr pt(new int(42));

我们先来看看unique_ptr独有的一些操作(shared)ptr那些它都行): image

这里厉害了:unique_ptr不支持普通的拷贝或赋值(因为它独有啊,霸道啊),拷贝给你了不是有两个指向那个内存了吗?

不过啊,我们可以调用一些函数来将所有权从一个unique_ptr(非const)转移给另一个unique_ptr:

unique_ptr p1(new string("hello"));
unique_ptr p2(p1.release()); //p2被初始化为p1原来保存的指针,而将p1置空
unique_ptr p3(new string("hi"));
p2.reset(p3.release); //跟上面效果一样,但形式不同,因为这里不是初始化了,算是赋值
p2.release(); //我们把指针置空了,却没有释放内存。。。

传递unique_ptr和返回unique_ptr

不能拷贝unique_ptr有例外:可以拷贝或赋值一个将要被销毁的unique_ptr:

//函数返回一个unique_ptr
unique_ptr clone(int p)
{
    return unique_ptr(new int(p)); //正确:int*隐式转换到unique_ptr
}
//返回一个局部对象的拷贝
unique_ptr Clone(int p)
{
    unique_ptr ret(new int(p));
    return ret; 
}

对于上面这两个函数,编译器很聪明,它知道要返回的对象将要被销毁,所以它会执行一种特殊的拷贝(以后再介绍)。

向unique_ptr传递删除器

unique_ptr默认还是delete删除,也支持自定义,但是它这个自定义很特殊(以后再解释原因),我们来看一下格式(比较复杂的):

unique_ptr p (new objT, fcn);
//p指向一个类型为objT的对象,并使用类型为delT的对象释放objT对象
//怎么释放呢?它会调用delT类型对象fcn


weak_ptr

一听名字就很弱,它其实是来占shared_ptr便宜的。 weak_ptr指向由shared_ptr管理的对象,但不改变引用计数 它的操作如下图:

image

auto p = make_shared(24); 
weak_ptr wp(p); //创建weak_ptr要用shared_ptr来初始化它
//由于对象可能不存在,我们在用weak_ptr访问时要调用lock函数来检查对象是不是还在
if(shared_ptr np = wp.lock()) //如果对象存在,lock返回该对象的shared_ptr
{
    //在这用np访问是安全的
}

我们可能觉得这个weak_ptr没啥大用,那我们就来举个例子,说明它还是有用的。

核查指针类

还记得我们最开始的StrBolb类吗,我们要为它定义一个指针类StrBlobPtr,可以指向它的对象,该指针会保存一个weak_ptr,指向StrBlob的data成员(在初始化时给它的)。

为什么要用weak_ptr呢?因为它不会影响一个给定的StrBlob所指向的vector的生存期,但是它可以阻止用户访问一个不存在的vector:

class StrBlobPtr
{
public:
    StrBlobPtr() : curr(0){}
    StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz){}
private:
    shared_ptrstring> check(size_t, const string&) const; //检查下标合法性
    weak_ptr> wptr; //指向vector的弱指针
    size_t curr; //记录在数组中的当前位置
};

我们要定义一下check函数,它不仅要检查下标的合法性,还要负责检查指向的vector还在不在:

shared_ptr> StrBlobPtr::check(size_t i, const string &msg) const
{
    auto ret = wptr.lock; //vector还在吗
    if(!ret)
    {
        throwruntime_error("空悬指针了啊");
    }
    if(i >= ret->size())
    {
        throw out_of_range(msg);
    }
    return ret; //成功的话返回指向vector的shared_ptr
}
#C++工程师#
全部评论

相关推荐

不愿透露姓名的神秘牛友
02-12 10:05
小米集团 算法工程师 28.0k*15.0
泡沫灬一触即破:楼上那个看来是看人拿高薪,自己又不如意搁这泄愤呢是吧,看你过往评论很难不怀疑你的精神状态
点赞 评论 收藏
分享
点赞 评论 收藏
分享
01-16 18:48
四川大学 Java
KalznAsawind:人问他哪一个是pdd,他倒介绍起来了。。。
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务