最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

C++ Primer 序章:unique_ptr 和 weak_ptr

XAMPP案例 admin 33浏览 0评论
动态内存
直接管理内存
我们讲了那么多,只是讲了三个智能指针中的一个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 那些它都行):
dz0027xampp
这里厉害了: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 管理的对象,但不改变引用计数 它的操作如下图:
dz00027xampp
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
}

转载请注明:XAMPP中文组官网 » C++ Primer 序章:unique_ptr 和 weak_ptr