码迷,mamicode.com
首页 > 其他好文 > 详细

优先使用make_unique 和 make_shared

时间:2021-06-15 18:01:41      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:invoke   内存分配   初始化列表   ted   div   strong   显示   std   空间   

make_unique在c++11里面没有引入,但是你可以自己写一个

template <typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args) {
    return unique_ptr<T>(new T(std::forward<Args>(args)...));
}

使用make版本和使用new的本质不同

  1. make版本不需要显示的使用new, 如果是unique就使用make_unique,如果是shared就是用make_shared;

    不依赖于显式new的这种方式,在库之间依赖的时候通常减少了很多bug出现

    同时减少代码的大小

    1. 避免异常安全

    对于函数 void invoke(shared_ptr memory, int value);

    我们调用 invoke(shared_ptr(new int()), getMemory());,这种方式存在潜在的异常安全

    期待的顺序为

    new int
    shared_ptr 得到int内存
    调用getMemory()
    

    但是编译器可能调整函数上的调用顺序

    new int
    调用getMemory()
    shared_ptr 得到int内存
    

    如果调用getMemory出现了异常,那么 new出来的空间就内存泄漏

    修改的方式:

    1. 使用 make版本,他让 new和shared一体化

    2. 在外部使用shared_ptr,为了效率也可以使用std::move(),使用移动好处多多对吧

      shared_ptr<int> test(new int());
      invoke(std::move(test), getMemory());
      
    3. 效率

    shared_ptr(new int())

    如果是这样调用,造成的内存分配就是两次,一个是new,一个是内部的control block的内存分配

    使用make版本代替

    这样的话,make版本内部使用allocated一下子分配包含new和control block的内存大小空间,并且这样加快程序运行速度、减小内存碎片的分配

额外需要使用new的情况

  1. 想要自己提供额外的析构器,需要使用主动new
  2. 初始化列表,make版本默认内部使用()调用,无法使用{}初始化列表;但是也可以外面自己构建一个{}初始化列表,然后使用()传递进去
  3. 那些重载了new和delete的类,因为一般情况下类的特殊内存重载都是针对于类本身大小来做的,但是make版本的分配是类大小加上control block的内存大小空间,所以需要使用显式new
  4. 因为make版本是把类大小加上control block的内存大小放在一起分配的空间,那么即使内部引用计数为0,也需要等到control block被销毁才能被销毁(因为weak_ptr的问题),也就是只有当weak_count为0,control Block这片内存才会释放;这也就延长了动态分配的chunk的内存存活期

优先使用make_unique 和 make_shared

标签:invoke   内存分配   初始化列表   ted   div   strong   显示   std   空间   

原文地址:https://www.cnblogs.com/chaohacker/p/14883727.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!