c/c++ 智能指针 shared_ptr 和 new结合使用

智能指针 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;                                                            
  */
}

github完整代码

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

1414315-20180928072538667-836855118.jpg

本人微信:xiaoshitou5854

转载于:https://www.cnblogs.com/xiaoshiwang/p/9716606.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
shared_ptrC++中的智能指针,它采用引用计数的方法来实现释放指针所指向的资源。当使用shared_ptr时,它会记录有多少个shared_ptr指向同一个对象,只有当最后一个shared_ptr被销毁时,该对象的内存才会被释放。因此,shared_ptr可以自动管理内存,不需要手动释放。 在代码中,使用shared_ptr可以像普通指针一样操作对象。当需要创建一个shared_ptr对象时,可以使用std::make_shared函数来构造,如下所示: ``` std::shared_ptr<int> sharedPtr1 = std::make_shared<int>(10); ``` 可以通过将shared_ptr赋值给其他shared_ptr来共享资源,如下所示: ``` std::shared_ptr<int> sharedPtr2 = sharedPtr1; ``` 当所有的shared_ptr都被销毁时,内存会自动释放。可以使用use_count()函数获取shared_ptr的引用计数,如下所示: ``` std::cout << "sharedPtr2 use count: " << sharedPtr2.use_count() << std::endl; ``` 当引用计数为0时,内存会被自动释放。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++智能指针shared_ptr分析](https://download.csdn.net/download/weixin_38705004/13788082)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解](https://blog.csdn.net/chenlycly/article/details/130918547)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值