<二>智能指针之__unique_ptr

unique_ptr建议使用场景和不建议场景

场景1

//原生指针没有所有权
void f()
{
    // 不好: 原生指针拥有了所有权,不推荐写法!!
    int* p1 = new int{7}; 
    ..
    ..
}

template<typename T>
class X {
    public:
    T* p; // 不好: 不清楚 p 所有权 不推荐写法!!
    T* q; // 不好: 不清楚 q 所有权 不推荐写法!!
    ..
    ..
};

// 不好: 不清楚返回值所有权  不推荐写法!!
Gadget* make_gadget(int n) 
{
    Gadget* p = new Gadget{n};
    ..
    ..
    return p;
}

void caller(int n)
{
    // 要记得 delete p  不推荐写法!!
    Gadget* p = make_gadget(n); 
    ..
    ..
    delete p;
}

//返回函数内存申请资源的所有权
unique_ptr<Gadget> func(int x)
{
    unique_ptr<Gadget> p(new Gadget(x));//自动将pdelete
    return p;
}
int main()
{
    int a = 5;
    unique_ptr<Gadget> ret = func(a);//自动将ret,delete
    cout << *ret << endl;
    //函数结束自动释放new的资源
}

场景2

struct MyClass
{
   //推荐unique_ptr<Widget> p,当然如果 Widget w 能直接满足业务要求这种
   //直接定义对象的方式更好,但往往我们需要支持多态
   //的时候必须要使用指针的时候,那么这个时候应该使用
   //unique_ptr
    unique_ptr<Widget> p;
};

场景3

//函数传参时,下面的所有权发生转移,获取 widget 的所有权
void process1(unique_ptr<Widget> w)
{
    w->print();
}
unique_ptr<Widget> w(new widget());
process1(std::move(w));

场景4

//使用场景, 可行,不常用:打算重新指向别的对象
void process4(unique_ptr<Widget>&); 
//上面的方式更推荐写成下面,推荐下面方式, 仅仅使用这个 widget,不表达任何所有权
void process2(const Widget& w)
{
    w.print();
}
process2(*w);//调用方式

场景5

//可行, 仅仅使用这个 widget,不表达任何所有权 更建议 写成 void process2(const Widget& w)
void process3(Widget* w)
{
    w->print();
}

场景6

// 不推荐: 通常不是想要的
void process5(const unique_ptr<Widget>&); 

场景7

//工厂函数, 很推荐写法
unique_ptr<Widget> createWidget()
{
    unique_ptr<Widget> w(new Widget(0,0,0));

    return w;//这里相当于有 std::move(w) ;
}

场景8

//使用场景,容器中使用智能指针 如下

#include <memory>
#include <iostream>
using namespace std;

struct Node
{
    int data;
    std::unique_ptr<Node> next;

    ~Node()
    {
        cout<<"dtor: "<<data<<endl;
    }
};

struct List
{

    std::unique_ptr<Node> head;
 
    void push(int data)
    {
        head = std::unique_ptr<Node>(new Node{data, std::move(head)});
    }

    //解开析构函数的递归调用,防止栈溢出
    // ~List()
    // {
    //     while (head)
    //         head = std::move(head->next);
    // }
};

int main()
{
    
    List wall;
    for (int beer = 0; beer != 10; ++beer)
    {
        wall.push(beer);
    }

}

`关于Unique_Ptr小结``
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值