make_shared

C++——shared_ptr:make_shared的用处,与shared_ptr直接构造的区别 介绍了智能指针底层原理:资源指针、引用计数。介绍了make_shared的作用以及原理 阅读详情

  make_shared函数的主要功能是在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr;由于是通过shared_ptr管理内存,因此一种安全分配和使用动态内存的方法。

     如下为make_shared的使用:

    //p1指向一个值为"9999999999"的string
    shared_ptr<string> p1 = make_shared<string>(10, '9');  
     
    shared_ptr<string> p2 = make_shared<string>("hello");  
     
    shared_ptr<string> p3 = make_shared<string>();

从上述例子我们可以看出以下几点:
  1)make_shared是一个模板函数;
  2)make_shared模板的使用需要以“显示模板实参”的方式使用,如上题所示make_shared<string>(10, 9),如果不传递显示 模板实参string类型,make_shared无法从(10, '9')两个模板参数中推断出其创建对象类型。
  3)make_shared在传递参数格式是可变的,参数传递为生成类型的构造函数参数,因此在创建shared_ptr<T>对象的过程中调用了类型T的某一个构造函数。

2.make_shared模板实现
 

make_shared和shared_ptr的区别

struct A;
std::shared_ptr<A> p1 = std::make_shared<A>();
std::shared_ptr<A> p2(new A);

上面两者有什么区别呢? 区别是:std::shared_ptr构造函数会执行两次内存申请,而std::make_shared则执行一次。

std::shared_ptr在实现的时候使用的refcount技术,因此内部会有一个计数器(控制块,用来管理数据)和一个指针,指向数据。因此在执行std::shared_ptr<A> p2(new A)的时候,首先会申请数据的内存,然后申请内控制块,因此是两次内存申请,而std::make_shared<A>()则是只执行一次内存申请,将数据和控制块的申请放到一起。那这一次和两次的区别会带来什么不同的效果呢?

异常安全

考虑下面一段代码:

void f(std::shared_ptr<Lhs> &lhs, std::shared_ptr<Rhs> &rhs){...}

f(std::shared_ptr<Lhs>(new Lhs()),
  std::shared_ptr<Rhs>(new Rhs())
);

因为C++允许参数在计算的时候打乱顺序,因此一个可能的顺序如下:

  1. new Lhs()
  2. new Rhs()
  3. std::shared_ptr
  4. std::shared_ptr

此时假设第2步出现异常,则在第一步申请的内存将没处释放了,上面产生内存泄露的本质是当申请数据指针后,没有马上传给std::shared_ptr,因此一个可能的解决办法是:

auto lhs = std::shared_ptr<Lhs>(new Lhs());
auto rhs = std::shared_ptr<Rhs>(new Rhs());
f(lhs, rhs);

而一个比较好的方法是使用std::make_shared。

f(std::make_shared<Lhs>(),
  std::make_shared<Rhs>()
);

make_shared的缺点

因为make_shared只申请一次内存,因此控制块和数据块在一起,只有当控制块中不再使用时,内存才会释放,但是weak_ptr却使得控制块一直在使用。

什么是weak_ptr?

weak_ptr是用来指向shared_ptr,用来判断shared_ptr指向的数据内存是否还存在了(通过方法lock),下面是一段示例代码:

#include <memory>
#include <iostream>
using namespace std;
struct A{
    int _i;
    A(): _i(int()){}
    A(int i): _i(i){}
};

int main()
{
    shared_ptr<A> sharedPtr(new A(2));
    weak_ptr<A> weakPtr = sharedPtr;
    sharedPtr.reset(new A(3)); // reset,weakPtr指向的失效了。
    cout << weakPtr.use_count() <<endl;
}

通过lock()来判断是否存在了,lock()相当于

expired()?shared_ptr<element_type>() : shared_ptr<element_type>(*this)

当不存在的时候,会返回一个空的shared_ptr,weak_ptr在指向shared_ptr的时候,并不会增加ref count,因此weak_ptr主要有两个用途:

  1. 用来记录对象是否存在了
  2. 用来解决shared_ptr环形依赖问题

weak_ptr解决环形依赖

下面是存在环形依赖的代码:

include <memory>
include <iostream>

using namespace std;
struct B;
struct A { shared_ptr<B> b;};
struct B { shared_ptr<A> a;};


int main()
{
    shared_ptr<A> x(new A);
    //x->b = new B; // wrong
    //x->b = shared_ptr<B>(new B);
    x->b = make_shared<B>();
    x->b->a = x;
    cout << x.use_count() <<endl;
    cout << x->b.use_count() <<endl;
    // Ref count of 'x' is 2.
    // Ref count of 'x->b' is 1.
    // When 'x' leaves the scope, there will be a memory leak:
    // 2 is decremented to 1, and so both ref counts will be 1.
    // (Memory is deallocated only when ref count drops to 0)
}

下面是解决方案:

shared_ptr<A> x(new A);
//x->b = new B; // wrong
//x->b = shared_ptr<B>(new B);
x->b = make_shared<B>();
x->b->a = x;
cout << x.use_count() <<endl;
cout << x->b.use_count() <<endl;
// Ref count of 'x' is 1.
// Ref count of 'x->b' is 1.
// When 'x' leaves the scope, its ref count will drop to 0.
// While destroying it, ref count of 'x->b' will drop to 0.
// So both A and B will be deallocated.   cout << x->b.use_count() <<endl;

一个自然而然的问题是:weak_ptr是否能够当编程人员不清楚拥有权的情况下解决环形依赖呢?

答案是不能,当对象之间的拥有权不清楚的时候,weak_ptr并不能带来帮助。如果存在环,必须要找出来,然后手动打破。那怎么能够解决环形依赖呢?可以使用有完整垃圾回收机制的语言如Java,Go,Haskell,或者使用有些缺陷的垃圾回收器(C/C++)Boehm GC)。

为什么weak_ptr使得控制块一直使用呢?

我们想下,当要使用weak_ptr来获取shared_ptr的时候,需要得到指向数据的shared_ptr数目,而这正是通过user-count来得到的,而这块内存是分配在shared_ptr中的,自然有使用的,那就不会释放了,即使数据引用数为0了,但是由于make_shared()使得数据和控制块一起分配,自然只要有weak_ptr指向了控制块,就不会释放整块内存了。

weak_ptr的使用注意

下面有段代码:

shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);

// some time later

if(int * r = q.get())
{
    // use *r
}

如果在多线程中,在if之后,但是在使用*r之前,另一个线程对p进行了reset,那次后在使用*r则会抛出异常,一个解决方法就是:

shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);

// some time later

if(shared_ptr<int> r = q.lock())
{
    // use *r
}

此时r指向了数据,就不怕被释放了,因此在使用weak_ptr的时候,应使用lock方法转换成shared_ptr后使用。

智能指针使用Tip

2018年04月15日 13:47:17 CPriLuke 阅读数:51 标签: shared_ptr 智能指针 内存管理 更多

个人分类: C/C++

C++11引入shared_ptr,unique_ptr,weak_ptr后,大大简化了c++对动态内存的管理,为了能更好的发挥智能指针的优势,且避免不必要的异常,下面总结了使用智能指针的的一些注意事项:

 

1.智能指针是行为像指针的类,其本质是一个类,其原理是通过构造/拷贝/赋值/析构操作来维护引用计数,从而达到对资源的管理,且该资源不仅仅限于动态内存;
比如:可以通过智能指针管理tcp的连接与端口;

 
  1. {

  2. int handle = tcp_nenect(ip_addr, port_num);

  3. shared_ptr<int> p((int*)handle, [](int* h) {tcp_disconnect((int)h);}; //

  4.  
  5. //离开作用域时,自动断开连接

  6. ....

  7. }

2.尽量不用get()函数返回智能指针保存的指针,而是直接采用解引用运算符(*/);为了解决这个问题,是需要知道我们在什么情况下使用get(),及其对应的替换方式
情形一:智能指针类型为动态数组,通过get()返回头指针进行指针运算.(智能指针不支持),
此种情形最好将内置数组换成vector或array容器;

 
  1. unique_ptr<int[]> parray(new int[10]);

  2. int *begin = parray.get(); //通过get()返回头指针

  3. int *end = begin + 10;

  4.  
  5. fill(begin, end, 10);

  6. for_each(begin, end, [](const int& p) {

  7. cout<< p << " ";

  8. }); //打印 10 10 10 ...10

  9. cout<<endl;

  10.  
  11. //采用解引用

  12. for(int i = 0;i < 10; i++)

  13. parray[i] = 12;

  14.  
  15. for(int i = 0;i < 10; i++)

  16. cout<< parray[i] << " ";

情形二:通过指针访问指向对象的成员

 
  1. shared_ptr<pair<string, int>> ps = make_shared<pair<string, int>>(string("hello"), 10);

  2. auto* pp = ps.get(); //多此一举,不提倡的用法

  3. cout<< pp->first << " " << pp->second << endl;

  4.  
  5. cout<< ps->first << " " << ps->second << endl; //简单方便

3.当需要管理多个相同元素时,不要用内置数组,建议使用vector或array容器;之所以不使用内置数组,是由于shared_ptr<>不直接支持动态数组管理,且无法高效使用标准库

 
  1. //shared_ptr类型为内置数组必须声明删除器为delete[]

  2. shared_ptr<int> sp(new int[10], [](int*p) { delete[] p; } );

  3.  
  4. //建议方法

  5. shared_ptr<vector<int>> sp = make_shared<vector<int>>(10, 1);

  6. for_each(sp->begin(), sp->end(), [](int &e) {cout<< e << " "; } );

4.尽量不能混用普通指针和智能指针,尤其是以下几点:
  ①不使用相同的内置指针初始化(或reset)多个智能指针,正确方式如下:

 
  1. shared_ptr<int> p(new int(10)); //ok,但提倡使用make_pair

  2. p.reset(new int(42)); //ok

  ②不delete get()返回的指针
  ③不使用get()初始化或reset另一个智能指针
  ④如果使用get()返回的指针,当对应的最后一个智能指针销毁后,此指针就无效了

反正上面四点记也挺麻烦,easy一点,就是别混用两者,甚至只使用智能指针;

5.使用make_pair初始化智能指针更简单,更安全

 
  1. shared_ptr<vector<int>> sp = make_shared<vector<int>>(10, 1); //运用的v(n, )构造

  2.  
  3. shared_ptr<pair<string, int>> ps = make_shared<pair<string, int>>(string("hello"), 10);

  4.  
  5. shared_ptr<vector<int>> sp = make_shared<vector<int>>(vector<int>{1,2,3,4,5}); //不能少vector<int>

6.采用typedef关键字定义智能指针类型避免表达式过长

 
  1. //改写上面的表达式

  2. typedef vector<int> vint ;

  3. typedef shared_ptr<vector<int>> vi_sptr ;

  4.  
  5. vi_sptr sp1 = make_shared<vint>(10, 1);

  6. vi_sptr sp2 = make_share<vint>(vint{1,2,3,4,5});

7.使用weak_ptr前请先lock()

 
  1. //正确使用方式

  2. if(share_ptr<int> np = wp.lock()) //如果np不为空则条件成立

  3. {

  4. //正常使用np进行操作

  5. }

Make_shared

Why Make_shared ?

C++11 中引入了智能指针, 同时还有一个模板函数 std::make_shared 可以返回一个指定类型的 std::shared_ptr, 那与 std::shared_ptr 的构造函数相比它能给我们带来什么好处呢 ?

优点

效率更高

shared_ptr 需要维护引用计数的信息,

  • 强引用, 用来记录当前有多少个存活的 shared_ptrs 正持有该对象. 共享的对象会在最后一个强引用离开的时候销毁( 也可能释放).
  • 弱引用, 用来记录当前有多少个正在观察该对象的 weak_ptrs. 当最后一个弱引用离开的时候, 共享的内部信息控制块会被销毁和释放 (共享的对象也会被释放, 如果还没有释放的话).

如果你通过使用原始的 new 表达式分配对象, 然后传递给 shared_ptr (也就是使用 shared_ptr 的构造函数) 的话, shared_ptr 的实现没有办法选择, 而只能单独的分配控制块:

1
2
 
  1. auto p = new widget();

  2. shared_ptr sp1{ p }, sp2{ sp1 };

  3.  

如果选择使用 make_shared 的话, 情况就会变成下面这样:

1
 
  1. auto sp1 = make_shared(), sp2{ sp1 };

  2.  

内存分配的动作, 可以一次性完成. 这减少了内存分配的次数, 而内存分配是代价很高的操作.

关于两种方式的性能测试可以看这里 Experimenting with C++ std::make_shared

异常安全

看看下面的代码:

1
2
3
4
 
  1. void F(const std::shared_ptr<Lhs>& lhs, const std::shared_ptr<Rhs>& rhs) { /* ... */ }

  2.  
  3. F(std::shared_ptr<Lhs>(new Lhs("foo")),

  4. std::shared_ptr<Rhs>(new Rhs("bar")));

  5.  

C++ 是不保证参数求值顺序, 以及内部表达式的求值顺序的, 所以可能的执行顺序如下:

  1. new Lhs(“foo”))
  2. new Rhs(“bar”))
  3. std::shared_ptr
  4. std::shared_ptr

好了, 现在我们假设在第 2 步的时候, 抛出了一个异常 (比如 out of memory, 总之, Rhs 的构造函数异常了), 那么第一步申请的 Lhs 对象内存泄露了. 这个问题的核心在于, shared_ptr 没有立即获得裸指针.

我们可以用如下方式来修复这个问题.

1
2
3
 
  1. auto lhs = std::shared_ptr<Lhs>(new Lhs("foo"));

  2. auto rhs = std::shared_ptr<Rhs>(new Rhs("bar"));

  3. F(lhs, rhs);

  4.  

当然, 推荐的做法是使用 std::make_shared 来代替:

1
 
  1. F(std::make_shared<Lhs>("foo"), std::make_shared<Rhs>("bar"));

  2.  

缺点

构造函数是保护或私有时,无法使用 make_shared

make_shared 虽好, 但也存在一些问题, 比如, 当我想要创建的对象没有公有的构造函数时, make_shared 就无法使用了, 当然我们可以使用一些小技巧来解决这个问题, 比如这里 How do I call ::std::make_shared on a class with only protected or private constructors?

对象的内存可能无法及时回收

make_shared 只分配一次内存, 这看起来很好. 减少了内存分配的开销. 问题来了, weak_ptr 会保持控制块(强引用, 以及弱引用的信息)的生命周期, 而因此连带着保持了对象分配的内存, 只有最后一个 weak_ptr 离开作用域时, 内存才会被释放. 原本强引用减为 0 时就可以释放的内存, 现在变为了强引用, 若引用都减为 0 时才能释放, 意外的延迟了内存释放的时间. 这对于内存要求高的场景来说, 是一个需要注意的问题. 关于这个问题可以看这里 make_shared, almost a silver bullet

参考

 

 

转载自:http://bitdewy.github.io/blog/2014/01/12/why-make-shared/

c++ make_shared的使用及注意事项 在 C++11 中,可以使用 make_shared 函数来创建共享指针,它是一个模板函数,可以接受任何类型的参数,并返回一个指向该类型对象的共享指针。它可以将控制块和对象一起分配在堆上,从而避免了两次内存分配,并减少了引用计数的内存开销,相对于直接使用。其中,T 表示指向的类型,Args 是类型 T 的构造函数所需的参数列表,在调用时需要传递给构造函数。是 C++11 提供的一种高效、安全的智能指针工厂函数,使用起来方便且实用。来创建一个较大的对象,可能会增加堆分配的消耗。在上面的代码中,我们使用。 阅读详情

相关推荐

C++(11):make_shared

而函数调用2由于参数a只有一个顶层表达式,所以是不会被打断,比如完整的执行的,因此即使执行完,doSomethingGetB产生了异常,那么shared_ptr也会在栈展开的过程中被释放,不会造成内存泄漏。那么这3个表达式本身是不允许中断的,比如不允许 new A执行了一半去执行doSomethingGetB。C++规定,函数的顶层实参的求值没有强制的顺序,所以对于函数a和b的求值没有强制的规定谁先进行。那么如果(3)抛出一个异常,而裸指针tmp还没有初始化给shared_ptr,那么就会造成内存泄漏。

风静如云的博客 6521

C/C++编程:理解make_shared

shared_ptr<string> p1 = make_shared<string>(10, '9'); shared_ptr<string> p2 = make_shared<string>("hello"); shared_ptr<string> p3 = make_shared<string>();

OceanStar的博客 1万+

SICK LMS111激光雷达数据解析实战:从原始帧到三维点云的完整流程

本文详细解析了SICK LMS111激光雷达从原始数据帧到三维点云的完整处理流程,包括数据帧结构解析、坐标转换、点云可视化及性能优化技巧。通过实战代码示例,展示了如何高效处理激光雷达数据,并应用于动态物体检测、地面分割等工业场景,为AGV和服务机器人开发者提供实用指南。

garlic的博客 769

C++11 make_shared函数和std::make_unique详解

如果使用std::unique_ptr和std::make_unique来替换std::shared_ptr和std::make_shared,事实上,会用到同样的理由。这样通过std::shared_ptr的make函数分配的函数则在最后一个std::shared_ptr和最后一个std::weak_ptr被销毁前不能被释放。假如我们把std::shared_ptr和std::make_shared替换成std::unique_ptr 和std::make_unique,会发生相同的事情。

二爷的博客 7247

Python+whisper/vosk实现语音识别

Whisper 是一个由 OpenAI 开发的人工智能语音识别模型,它能够将语音转换为文本。Whisper 模型特别之处在于它的设计目标是能够理解和转录多种语言的语音,包括但不限于英语。Whisper 模型在训练时使用了大量不同语言的语音数据,这使得它具有很好的跨语言能力。Vosk 是一个开源的语音识别库,它可以在离线环境下工作,不依赖于任何外部服务。Vosk 基于Kaldi语音识别框架,支持多种语言,包括中文。Vosk提供了多种预训练模型,可以根据需求选择适合的模型进行语音识别。

weixin_44458771的博客 5942

Dynamics CRM证书更换

  Dynamics CRM产品一般有两种认证方式。第一种是基于声明的内部访问也就是无证书单纯用账号密码验证。第二种就是联合身份认证,需要安装网站证书。   对于联合身份认证的情况因为需要安装证书,而且证书是有一个一年的有效期,所以运维人员每年都需要进行证书更换的操作。以下就是更换证书的方法及过程。 证书根据申请方式一般也分两种,第一种是自建证书,这种证书是没有机构认证的所以安装上之后网站因为没...

bzpfly的博客 877

make_shared理解

本章所有内容均从C++ Primer摘录总结1.为什么使用make_shared?    make_shared函数的主要功能是在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr;由于是通过shared_ptr管理内存,因此一种安全分配和使用动态内存的方法。     如下为make_shared的使用://p1指向一个值为"9999999999"的string shared_...

CPriLuke的博客 7万+

什么是OAuth 2.0?

OAuth2.0是一种授权协议而非登录协议,核心思想是通过令牌(Token)而非密码实现安全授权。它涉及三个关键角色:用户、第三方应用和身份提供商(IdP)。最常用的授权码流程(AuthorizationCode Flow)通过浏览器三方对话,确保用户密码只提供给IdP而非第三方应用。OAuth2.0提供四种授权方式,其中授权码和客户端凭证是当前主流,而隐式和密码模式已不推荐。需要注意的是,OAuth2.0解决的是授权问题,身份认证需通过OpenID Connect实现。该协议通过临时令牌机制,实现了&qu

sonadorje的专栏 1162

c++之make_shared特性

c++11版本引入了智能指针shared_ptr/unique_ptr等,本文重点讲解share_ptr相关。由于引入了shared_ptr,根据shared_ptr的定义可以知晓shared_ptr一个模板类,支持基本数据类型,自定义数据类型的共享指针的构造。但是直接使用shared_ptr可能会引入一些问题,例如内存泄露。上面的例子说明如果shared_ptr使用不当可能会导致内存泄露。要解决这个问题,有两种方法,一种是。

漫步者 1220

MIT 6.824分布式 LAB4A:ShardCtrler

lab 4要求实现一个使用raft共识算法的分片存储系统。而在lab 4a中,我们仅需实现分片控制器的功能。lab4中的分片存储系统有多个分片,这些数据分布在众多分片上,而每个分片都对应着一个集群组,可能一个集群组负责多个分片,一个集群组内的所有服务器都会使用raft共识算法进行状态的复制。而本实验的重点为分片控制器,主要负责的工作是对集群组和分片之间关系的管理,我们仅需在/src/shardctrler文件夹中对client.go,server.go,common.go这三个文件进行修改即可。注意事项(实

MarksSa的博客 832

基于YOLOv8和时序模型的异常动作检测系统

异常动作检测是计算机视觉领域的重要应用,广泛应用于智能监控、安防系统、老人看护等场景。本项目结合YOLOv8目标检测和LSTM时序模型,实现对打架、摔倒、奔跑等异常动作的实时检测,并提供了完整的Web界面。多技术融合: 结合YOLOv8目标检测和LSTM时序建模实时检测: 支持实时视频流处理和文件分析用户友好: 提供完整的Web界面可扩展性: 模块化设计便于功能扩展高性能: 包含多种优化策略。

YOLO 764

C++11 make_shared以及shared_ptr

make_shared的使用: shared_ptr<string> p1 = make_shared<string>(10, '9'); shared_ptr<string> p2 = make_shared<string>("hello"); shared_ptr<string> p3 = make_shared...

夏天Alex 1万+

从零构建爬虫抓取故宫数字文物库:Python最新实战技术详解

熟悉了动态内容加载的网页结构解析技巧。掌握了 Playwright + BeautifulSoup 的组合用法。实现了从网页→JSON→详情→图像的完整数据闭环。掌握了结构化保存与可视化分析能力。

2201_76125261的博客 1307

make_shared剖析

引言 关于make_shared,大家都知道可以用它来初始化shared_ptr: shared_ptr<string> sp = make_shared<string>(); 那为何要使用它呢,我们都知道,也可以直接通过shared_ptr的构造函数来生成shared_ptr对象: shared_ptr<string> sp1(new string()); 这两者有何区别呢?首先来看看make_shared源码: make_shared源码 template<

bureau123的博客 6426

[QMT量化交易小白入门]-八十九、深度学习训练多维特征进行金融价格行情预测

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。

木头大左的博客 218

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

make_shared()

*这种做法没有意义!**我们从堆区构建一个对象Object,地址给给指针op,当我们做共享指针pobja,pobjb后,会导致这个Object对象被重复释放。导致内存被重复释放。

ljy的博客 1135

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

make_shared的使用

如果在 ** 步骤 2(分配控制块)** 时发生异常(比如内存不足,抛出。这样要么全部成功,要么全部回滚,不会泄漏资源。,用于创建并返回一个指向动态分配对象的。它是创建共享所有权对象的标准推荐方式。3. make_shared 的核心优势。比传统方式快 10-30%是 C++11 引入的。

m0_73634434的博客 1569

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

make_shared、shared_ptr、enable_shared_from_this

make_shared 和 正常的 shared_ptr 构造函数异同!

John_ToStr的博客 1484

【make_shared的使用】

>

2d3d图像算法 halcon\opencv\c++\pcl\vtk\coluldcompare工具 程序员 学习者 2758

建议用make_shared代替shared_ptr

默认的删除器是delete,无法delete 数组或者文件了托管的资源延迟释放当当前shared_ptr是最后一个引用该资源的智能指针时,出作用域时,uses从1减到0,就直接把内存释放掉了,哪怕这里还有很多weak_ptr在观察着,没有关系,它们只是观察引用计数。当最后一个引用该资源的强智能指针把uses从1减到0的时候,就把托管的资源释放了。也就是说,我们原来这样使用的话:只要该资源没有强智能指针去引用它,所有引用该资源的强智能指针出作用域了,这个new int(10)资源是一定会马上释放的。

ljy的博客 977

c++ make_shared

make_shared的使用: shared_ptr<string> p1 = make_shared<string>(10, '9'); shared_ptr<string> p2 = make_shared<string>("hello"); shared_ptr<string> p3 = make_shared<string>(); 尽量使用make_shared初始化 C++11 中引入了智能指

大西瓜不甜的博客 5350

C++ 学习系列 -- 智能指针 make_shared 与 make_unique

c++ 11 中 引入了智能指针 shared_ptr,以及一个模板函数 make_shared 来生成一个制定类型的 shared_ptr。

qq_33775774的博客 3382

shared_ptr 和 make_shared 简介

shared_ptr 和 make_shared 简介

SimpleLearning 2107

C++ make_shared

在使用std::shared_ptr时,有两种不同的构造方式,如: #include <iostream> #include <memory> int main(){ std::shared_ptr<int> sp1(new int(10)); std::shared_ptr<int> sp2 = std::make_shared<int>(10); return 0; } C++11 中引入...

LIJIWEI0611的博客 3278

模板函数make_shared

模板函数 std::make_shared 可以返回一个指定类型的 std::shared_ptr。

始作俑者2的博客 337
上一篇: camel
下一篇: Simple_Wallet 在服务器端通过RPC操纵钱包
TuxedoLinux
博客等级 码龄9年 268粉丝 34原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值