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

时间:2022-12-24 18:06:09

智能指针 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

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

本人微信:xiaoshitou5854

c/c++ 智能指针 shared_ptr 和 new结合使用的更多相关文章

  1. c&sol;c&plus;&plus; 智能指针 shared&lowbar;ptr 使用

    智能指针 shared_ptr 使用 上一篇智能指针是啥玩意,介绍了什么是智能指针. 这一篇简单说说如何使用智能指针. 一,智能指针分3类:今天只唠唠shared_ptr shared_ptr uni ...

  2. C&plus;&plus;智能指针shared&lowbar;ptr

    shared_ptr 这里有一个你在标准库中找不到的—引用数智能指针.大部分人都应当有过使用智能指针的经历,并且已经有很多关于引用数的文章.最重要的一个细节是引用数是如何被执行的—插入,意思是说你将引 ...

  3. STL源码剖析-智能指针shared&lowbar;ptr源码

    目录一. 引言二. 代码实现 2.1 模拟实现shared_ptr2.2 测试用例三. 潜在问题分析 你可能还需要了解模拟实现C++标准库中的auto_ptr一. 引言与auto_ptr大同小异,sh ...

  4. 智能指针shared&lowbar;ptr的用法

    为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...

  5. 智能指针 shared&lowbar;ptr 解析

    近期正在进行<Effective C++>的第二遍阅读,书里面多个条款涉及到了shared_ptr智能指针,介绍的太分散,学习起来麻烦.写篇blog整理一下. LinJM   @HQU s ...

  6. 智能指针shared&lowbar;ptr

    // 智能指针会自动释放所指向的对象. // shared_ptr的应用场景是:程序需要在多个对象间共享数据 /* 先从应用场景入手吧,说矿工A发现了一个金矿. * 然后矿工A喊来了矿工B,一起开采, ...

  7. 智能指针shared&lowbar;ptr新特性shared&lowbar;from&lowbar;this及weak&lowbar;ptr

    enable_shared_from_this是一个模板类,定义于头文件<memory>,其原型为: template< class T > class enable_shar ...

  8. C&plus;&plus; 智能指针 shared&lowbar;ptr

    今天晚上去旁听了C++高级编程的课,其中提到智能指针.第一反映还以为是auto_ptr呢,一听才知道是share_ptr这个.哦,原来是C++11特性.大致的原因是auto_ptr有一点缺陷,而sha ...

  9. 标准库中的智能指针shared&lowbar;ptr

    智能指针的出现是为了能够更加方便的解决动态内存的管理问题.注:曾经记得有本书上说可以通过vector来实现动态分配的内存的自动管理,但是经过试验,在gcc4.8.5下是不行的.这个是容易理解的,vec ...

随机推荐

  1. 第一篇使用Markdown的文章

    一级标题 1 计算机 |计算机|科学| Foo 这段文字需要被强调 this is H1 ========== this is H2 ---------- 这是H1 这是H2 这是H3 这是H6 断好 ...

  2. 动态规划 - 最长递增子序列&lpar;LIS&rpar;

    最长递增子序列是动态规划中经典的问题,详细如下: 在一个已知的序列{a1,a2,...,an}中,取出若干数组组成新的序列{ai1,ai2,...,aim},其中下标i1,i2,...,im保持递增, ...

  3. 获取Android设备屏幕分辨率

    1.Android 4.3引入的wm工具: a.获取Android设备屏幕分辨率: adb shell wm size b.获取android设备屏幕密度: adb shell wm density ...

  4. db file sequential read等待事件的一点研究

    db file sequential read等待事件有3个参数:file#,first block#,和block数量. 这个等待事件有3个参数P1,P2,P3, 其中P1代表Oracle要读取的文 ...

  5. dmp文件导入的方法

    1,使用oracle的imp命令导入*.dmp文件 首先要明确知道,使用oracle的imp命令进行导入,要在一个空的数据库下,才是最好的,否则,数据表存在的话,就要先删除数据表中的数据 步骤1:禁用 ...

  6. Python 数据挖掘 工具包整理

    连接器与io 数据库 类别 Python R MySQL mysql-connector-python(官方) RMySQL Oracle cx_Oracle ROracle MongoDB pymo ...

  7. log4donet 的 一篇简单使用实例

    背景 最近在写一个Adapter,需要调用别的程序的DLL. Adapter使用的是C#还有.net的等方面的技术.今天在写log这块,就像尝试一下有没有“*”可以试试的.在网上搜罗了一番之后,决定 ...

  8. struct的匿名用法详解

    Go只提供类型而不用写字段名的方式,也就是匿名字段,也称为嵌入字段. 当匿名字段是一个struct的时候,那么这个struct所拥有的全部字段都被隐式地引入了当前定义的这个struct. 举个例子,看 ...

  9. MySQL数据性能优化-修改方法与步骤

    原文:http://bbs.landingbj.com/t-0-240421-1.html 数据库优化应该是每个设计到数据库操作应用必须涉及到的操作. 经常调试修改数据库性能主要有三个方面 1.MyS ...

  10. 树莓派进阶之路 &lpar;012&rpar; - 树莓派配置文档 config&period;txt 说明

    原文连接:http://elinux.org/RPi_config.txt 由于树莓派并没有传统意义上的BIOS, 所以现在各种系统配置参数通常被存在”config.txt”这个文本文件中. 树莓派的 ...