C++备忘录061:smart pointers gist of "Effective Modern C++"

Prefer lambda as custom deleter of std::unique_ptr
#include <memory>
#include <iostream>

struct S {};

auto del1 = [](S *) {};

void del2(S *) {};

int main() {
    std::cout << sizeof(std::unique_ptr<S, decltype(del1)>) << '\n';    // 8
    std::cout << sizeof(std::unique_ptr<S, void(*)(S*)>) << '\n';       // 16
}

When using the default deleter, you can reasonably assume that std::unique_ptr objects are the same size as raw pointers.

  1. Deleters that are function pointers genenrally cause the size of a std::unique_ptr to grow from one word to two.

  2. For deleters that are function objects, the change in size depends on how much state is stored in the function object.

  3. Stateless function objects (e.g., from lambda expressions with no captures) incur no size penalty

Converting a std::unique_ptr to a std::shared_ptr is easy
Performance implications of the reference count
  1. std::shared_ptr are twice the size of a raw pointer, because a pointer to the resouce plus a raw pointer to the control block

  2. Memory for the reference count must be dynamically allocated

  3. Increments and decrements of the reference count must be atomic

Specifying a custom deleter doesn’t change the size of a std::shared_ptr object
std::weak_ptr objects are the same size as std::shared_ptr objects, they make use of the same control blocks, and operations such as construction, destruction, and assignment involve atomic reference count manipulations
Prefer std::make_shared
  1. Exception safe

  2. Allows compilers to generate smaller, faster code. std::make_shared requires one memory allocation instead of two

Circumstances that std::make_shared can’t or shouldn’t be used
  1. custom deleter/custom allocator

  2. When std::initializer_list is used as constructor. Parameters of make functions are considered as paren initialzied. e.g., std::make_shared<std::vector<int>>(10, 20) initializes a vector with 10 values set to 20.

    auto initList = {10, 20};
    auto spv = std::make_shared<std::vector<int>>(initList)
    
  3. Control block is placed in the same chunk of memory as the managed object. The managed memory cannot be released until the control block has also been destroyed. As long as std::weak_ptr refer to a control block, the memory allocated by make, then cannot be deallocated untile the last std::shared_ptr and the last std::weak_ptr referring to it have been destroyed

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值