c/c++语言开发共享c/c++ 智能指针 shared_ptr 使用

智能指针 shared_ptr 使用 上一篇 “智能指针是啥玩意” ,介绍了什么是智能指针。 这一篇简单说说如何使用智能指针。 一,智能指针分3类:今天只唠唠shared_ptr shared_ptr unique_ptr weak_ptr 二,下表是shared_ptr和unique_ptr都支持 …

智能指针 shared_ptr 使用

上一篇,介绍了什么是智能指针。

这一篇简单说说如何使用智能指针。

一,智能指针分3类:今天只唠唠shared_ptr

  • shared_ptr
  • unique_ptr
  • weak_ptr

二,下表是shared_ptr和unique_ptr都支持的操作

操作 功能描述
shared_ptr<t> sp 空智能指针,可以指向类型为t的对象
unique_ptr<t> up 空智能指针,可以指向类型为t的对象
p 将p用作一个条件判断,如果p指向一个对象,则为true
*p 解引用p,获得它指向的对象
p->mem 等价于(*p).mem,访问p所指对象的mem成员
p.get() 返回p中保存的指针。如果指向的对象已经被释放,就是一个危险的指针
swap(p, q)或者p.swap(q) 交换p和q中的指针

上面操作的验证代码

#include <memory> #include <iostream> #include <vector>  using namespace std;  class test{ public:   test(int d = 0):data(d){cout << "cr:" << data << endl;}   ~test(){cout << "fr:" << data << endl;}   void fun(){     cout << "test func(" << data << ")" << endl;   } private:   int data; }; int main(){   //shared_ptr<test> sp = make_shared<test>();                                     test* pt = new test();   shared_ptr<test> sp(pt);   if(sp){     cout << "sp指向了对象" << endl;   }   (*sp).fun();   shared_ptr<int> isp;   if(!isp){     cout << "isp没有指向对象" << endl;   }   test* tmp1 = sp.get();   auto sp1 = make_shared<test>(10);   test* tmp2 = sp1.get();   swap(sp, sp1);   tmp1->fun();//0   tmp2->fun();//10   //sp和sp1所指向的对象被交换了   sp.get()->fun();//10   sp1.get()->fun();//0  }

三,下表是shared_ptr独有的操作

操作 功能描述
make_shared<t>(args) 返回shared_ptr,指向一个动态分配的类型为t的对象。使用args初始化此对象。
shared_ptr p是q的拷贝;递增q中的计数器。q中的指针必须能转化成t*。
p = q p和q都是shared_ptr,所保存的指针必须能相互转换。递减p的引用计数;递增q的引用计数;如果p的引用计数变为0,则释放p管理的对象的内存。
p.unique() 如果p.use_count()为1,则返回true;否则返回false
p.use_count() 返回与p共享对象的智能指针的数量;性能很低,用于调试。

上面操作的验证代码

  shared_ptr<test> tsp = make_shared<test>(11);   cout << tsp.use_count() << endl;//1                                              //tsp1和tsp指向相同的对象,这个对象的计数器加1                                   shared_ptr<test> tsp1(tsp);   cout << tsp.use_count() << endl;//2                                              //用tsp1改变了对象的data的值,所以用tsp再访问这个对象,发现对象被改变了           tsp1->setdata(111);   tsp->fun();//111                                                                  shared_ptr<test> q(new test(20));   cout << q.use_count() << endl;//1                                                cout << tsp.use_count() << endl;//2                                              //如果q不是智能指针,q指向的test(20)这块内存就泄露了                              //q是智能指针,所以自动释放了test(20)这块内存                                    q = tsp;   cout << q.use_count() << endl;//3                                                cout << tsp.use_count() << endl;//3                                              if(!q.unique()){     cout << "不是只有一个智能指针指向了某个对象" << endl;   }

四,智能指针作为函数的返回值

shared_ptr<test> hun(int d){   return make_shared<test>(d); } void use_hun1(int d){   shared_ptr<test> p = hun(d);   p->fun(); }//p离开作用域后,它指向的内存会被自动释放                                       shared_ptr<test> use_hun2(int d){   shared_ptr<test> p = hun(d);//计数器为1                                          return p;//返回p时,计数器递增,为2                                            }//离开作用域后,计数器递减,为1,因为不为0,所以不会释放

一到四的小例子:

include <memory> #include <iostream> #include <vector>  using namespace std;  class test{ public:   test(int d = 0):data(d){cout << "cr:" << data << endl;}   ~test(){cout << "fr:" << data << endl;}   void fun(){     cout << "test func(" << data << ")" << endl;   }   void setdata(int d){     data = d;   } private:   int data; };  //test3 智能指针作为函数的返回值                                                 shared_ptr<test> hun(int d){   return make_shared<test>(d); } void use_hun1(int d){   shared_ptr<test> p = hun(d);   p->fun(); }//p离开作用域后,它指向的内存会被自动释放                                       shared_ptr<test> use_hun2(int d){   shared_ptr<test> p = hun(d);//计数器为1                                          return p;//返回p时,计数器递增,为2                                            }//离开作用域后,计数器递减,为1,因为不为0,所以不会释放                        int main(){   //test1 shared_ptr和unique_ptr都支持的操作                                       /*                                                                               //shared_ptr<test> sp = make_shared<test>();                                     test* pt = new test();                                                           shared_ptr<test> sp(pt);                                                         if(sp){                                                                            cout << "sp指向了对象" << endl;                                                }                                                                                (*sp).fun();                                                                     shared_ptr<int> isp;                                                             if(!isp){                                                                          cout << "isp没有指向对象" << endl;                                             }                                                                                test* tmp1 = sp.get();                                                           auto sp1 = make_shared<test>(10);                                                test* tmp2 = sp1.get();                                                          swap(sp, sp1);                                                                   tmp1->fun();                                                                     tmp2->fun();                                                                     sp.get()->fun();                                                                 sp1.get()->fun();                                                                */    //test2 shared_ptr独有的操作                                                      /*                                                                               shared_ptr<test> tsp = make_shared<test>(11);                                    cout << tsp.use_count() << endl;//1                                              //tsp1和tsp指向相同的对象,这个对象的计数器加1                                   shared_ptr<test> tsp1(tsp);                                                      cout << tsp.use_count() << endl;//2                                              //用tsp1改变了对象的data的值,所以用tsp再访问这个对象,发现对象被改变了           tsp1->setdata(111);                                                              tsp->fun();//111                                                                                                                                                  shared_ptr<test> q(new test(20));                                                cout << q.use_count() << endl;//1                                                cout << tsp.use_count() << endl;//2                                              //如果q不是智能指针,q指向的test(20)这块内存就泄露了                              //q是智能指针,所以自动释放了test(20)这块内存                                    q = tsp;                                                                         cout << q.use_count() << endl;//3                                                cout << tsp.use_count() << endl;//3                                              if(!q.unique()){                                                                   cout << "不是只有一个智能指针指向了某个对象" << endl;                          }                                                                                */    //test3 智能指针作为函数的返回值                                                 /*                                                                               auto ap = use_hun2(22);                                                          ap->fun();                                                                       use_hun1(33);                                                                    */  }

五,智能指针的注意事项

把shared_ptr放入容器中时,之后不再需要全部元素,只使用其中一部分的话,要用erase删除那些不再需要使用的shared_ptr。如果不erase那些不再需要使用的shared_ptr,shared_ptr就不会释放它指向的内存。

六,智能指针的小例子,让多个对象共享相同的状态。

  • 有个类shared_vector,里面有个shared_ptr,指向了一个vector,类shared_vector的对象a2拷贝a1时,实现a1和a2共享vector。
  • 类un_shared_vector没有使用shared_ptr,所以没有共享vector。
include <iostream> #include <memory> #include <vector> #include <string>  using namespace std;  class shared_vector{ public:   typedef vector<string>::size_type size_type;   shared_vector():data(make_shared<vector<string>>()){}   shared_vector(initializer_list<string> il):     data(make_shared<vector<string>>(il)){}   size_type size()const{return data->size();}   bool empty()const{return data->empty();}   //尾部插入,删除元素                                                             void push_back(const string& s){data->push_back(s);}   void pop_back(){data->pop_back();}   //访问元素                                                                       string& front(){return data->front();}   string& back(){return data->back();}  private:   shared_ptr<vector<string>> data; };  class un_shared_vector{ public:   typedef vector<string>::size_type size_type;   un_shared_vector():data(vector<string>()){}   un_shared_vector(initializer_list<string> il):data(il){}   size_type size()const{return data.size();}   bool empty()const{return data.empty();}   //尾部插入,删除元素                                                             void push_back(const string& s){data.push_back(s);}   void pop_back(){data.pop_back();}   //访问元素                                                                       string& front(){return data.front();}   string& back(){return data.back();}  private:   vector<string> data; };  int main(){   shared_vector sv{"aa","bb"};   shared_vector sv1(sv);   //因为sv和sv1共享同一个vector,                                                  //所以通过sv改变vector后,通过sv1也发现了相同的改变   sv.push_back("cc");   cout << sv1.back() << endl;    un_shared_vector usv{"11","22"};   un_shared_vector usv1(usv);   //因为usv和usv1不共享同一个vector,                                              //所以通过usv改变vector后,usv1里面的vector没有跟着变化   usv.push_back("33");   cout << usv1.back() << endl;   cout << usv.back() << endl; }

c/c++ 学习互助qq群:877684253

c/c++ 智能指针 shared_ptr 使用

本人微信:xiaoshitou5854

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/607590.html

(0)
上一篇 2021年5月14日
下一篇 2021年5月14日

精彩推荐