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小结``