c/c++ 智能指针 shared_ptr 和 new结合使用
程序员文章站
2022-07-02 14:41:19
智能指针 shared_ptr 和 new结合使用 用make_shared函数初始化shared_ptr是最推荐的,但有的时候还是需要用new关键字来初始化shared_ptr。 一,先来个表格,唠唠new和shared_ptr | 操作 | 功能描述 | | | | | shared_ptr\ ......
智能指针 shared_ptr 和 new结合使用
用make_shared函数初始化shared_ptr是最推荐的,但有的时候还是需要用new关键字来初始化shared_ptr。
一,先来个表格,唠唠new和shared_ptr
操作 | 功能描述 |
---|---|
shared_ptr<t> p(q) | 智能指针p管理内置指针q所指向的对象;q必须指向new分配的内存,且能够转换为t*。 |
shared_ptr<t> p(u) | p从unique_ptr u那里接管了原来u所指向对象的所有权,并将u置为空。 |
shared_ptr<t> p(q, d) | p接管了内置指针q所指的对象的所有权。q必须能转换为t*。p将使用可调用对象d来代替delete。 |
p.reset() | 如果p是唯一指向其对象的shared_ptr,reset会释放此对象。如果没传参数q,将p置为空。 |
p.reset(q) | 如果传递了内置指针q,会让p指向q所指向的对象,否则会将p置为空。 |
p.reset(q, d) | 如果还传递了参数d,将会调用d,而不是delete来释放q |
二,智能指针和普通指针一起使用的陷阱
void pro(shared_ptr<int> ptr){ } shared_ptr<int> p(new int(42));//计数器为1 pro(p);//p作为参数会进行copy递增它的计数器,在pro内部计数器是2 int i = *p;//计数器为1 cout << i << endl; int* bad = new int(11); //pro(bad);//编译错误 pro(shared_ptr<int>(bad));//合法,但出了pro,bad所指向的内存会被释放 int j = *bad;//解指针bad就会产生难以预料的结果
三,也不要使用get初始化另一个智能指针或为智能指针赋值
shared_ptr<int> p(new int(12)); int* q = p.get(); { shared_ptr<int> tmp(q); }//程序块结束后,q所指向的对象被释放 int f = *p;//解指针p就会产生难以预料的结果 cout << f << endl;
四,智能指针和异常
void f(){ shared_ptr<int> sp(new int(11)); //假设抛出了异常,而且在f中未捕获 }//函数结束后shared_ptr自动释放内存 void f1(){ int* ip = new int(12); //假设delete语句前抛出了异常,而且在f中未捕获 delete ip; }//函数结束后ip所指向的内存没有被释放。
五,智能指针使用的最佳建议
- 不使用相同的内置指针初始化(或reset)多个智能指针。
- 不使用get()初始化或reset另一个智能指针。
- 不delete get()返回的指针。
- 如果使用了get()返回的指针,请牢记,当最后一个对应的智能指针被销毁后,你的指针就变为无效了。
- 如果使用智能指针管理的资源不是new分配的内存,请传递给它一个删除器。
小例子:
#include <iostream> #include <memory> #include <vector> using namespace std; class test{ public: test(int d = 0) : data(d){cout << "new:" << data << endl;} ~test(){cout << "del:" << data << endl;} private: int data; }; void my_deleter(test* t){ cout << "my_deleter is work" << endl; } void pro(shared_ptr<int> ptr){ } int main(){ //test1 reset /* test* tp = new test(1); shared_ptr<test> stp(tp); shared_ptr<test> stp1(stp); stp.reset(); cout << stp << endl; */ //test2 自定义删除器 /* test* tp = new test(1); //不会调用test的析构函数了,只调用my_deleter函数 shared_ptr<test> stp(tp, my_deleter); shared_ptr<test> stp1(stp); cout << stp.use_count() << endl; test* tp1 = new test(2); stp1.reset(tp1, my_deleter); */ //test3 不要混用普通指针和智能指针 /* shared_ptr<int> p(new int(42));//计数器为1 pro(p);//p作为参数会进行copy递增它的计数器,在pro内部计数器是2 int i = *p;//计数器为1 cout << i << endl; int* bad = new int(11); //pro(bad);//编译错误 pro(shared_ptr<int>(bad));//合法,但出了pro,bad所指向的内存会被释放 int j = *bad;//解指针bad就会产生难以预料的结果 */ //test4 get的错误使用 /* shared_ptr<int> p(new int(12)); int* q = p.get(); { shared_ptr<int> tmp(q); }//程序块结束后,q所指向的对象被释放 int f = *p;//解指针p就会产生难以预料的结果 cout << f << endl; */ }
c/c++ 学习互助qq群:877684253
本人微信:xiaoshitou5854
上一篇: 害羞大哥幽默登场