关于 make_unique 和 make_shared

C++14 才加入make_unique , 据说当时忘记实现了。 那么C++11 可以自己实现这个功能:

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

关于这个函数,有几点要提的:

1.关于template<typename T, typename...  Args>

        这里面提到 typename ...    ||。详情可以看:https://zh.cppreference.com/w/cpp/language/parameter_pack

总结一下:

模板参数包是接受零个或多个模板参数(非类型、类型或模板)的模板参数。函数参数包是接受零个或多个函数参数的函数参数。具有至少一个参数包的模板称为可变参数模板

2. 为什么需要实现make_unique(参照 effective modern c++ 第21条),make系列有一些好处。

        除了填补make_shared 已经实现了,便于使用外。 还有如下原因:

        a.避免重复的冗余,因为new 版本书写了两次类型(Widget),源代码中的重复会导致目标代码笼肿。

        b. 避免有可能发生的内存泄漏。

        c. 使用make系列,可以让编译器有机会优化出更小更快的代码。

如下:

//1.new版本和 make_unique 版本
std::unique_ptr<Widget> ptr2(new Widget);

std::unique_ptr<Widget> ptr1(make_unique<Widget>());

//2. 使用new版本在函数调用中可能存在的问题。

  void processWidget(std::shared_ptr<Widget> spw, int priority);//声明
  void processWidget(std::shared_ptr<Widget> (new Widget), computePriority());//new 调用
/*函数的参数调用顺序是不确定的。倘若调用顺序如:
1.Widget tmpW = new Widget 
2.computerPriority() 
3.share_ptr<widget> tmpPtr = tmp;
假设在函数执行到computerPriority()时,异常 那么则会出现内存泄漏。
因为,tmpW并没有让share_ptr接管到, 这种错误是很隐晦的。*/

 3 .补充第二点,有些情况是不能使用make系列的。

        1) 当需要用到自定义析构函数时,如:

std::shared_ptr<Widget> spw(new Widget,widgetDeleter);

        2)当想使用std::initializer_list 型别的形参来重载构造函数,如:

auto initList={10,20};
auto spv=std::make_shared<std::vector<int>>(initList);

4.对于std::shared_ptr ,不建议使用make系列函数的额外场景包括(比较少的情况):

        a) 自定义内存管理类

        b) 内存紧张的系统,非常大的对象,以及存在比指涩到相同对象的std::shared_ptr生存期更久 的std::weak_ptr;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值