<!-- .slide: data-background="#ccc" -->

# `std::shared_ptr<>`

___

### `std::shared_ptr<>`

* <!-- .element: class="fragment fade-in" --> one object == multiple owners
* <!-- .element: class="fragment fade-in" --> last referrer destroys the object
* <!-- .element: class="fragment fade-in" --> copying allowed
* <!-- .element: class="fragment fade-in" --> moving allowed
* <!-- .element: class="fragment fade-in" --> can use custom deleter
* <!-- .element: class="fragment fade-in" --> can use custom allocator
* <!-- .element: class="fragment fade-in" --> has a control block == impact on size of pointer end efficiency

<img data-src="img/sharedptr1inverted.png" alt="shared pointers" class="plain fragment fade-in">

___
<!-- .slide: style="font-size: 0.85em" -->

### `std::shared_ptr<>` usage (1)

* Copying and moving is allowed

<div class="multicolumn">
<div class="col">

```cpp
std::shared_ptr<MyData> source();
void sink(std::shared_ptr<MyData> ptr);

void simpleUsage() {
    source();
    sink(source());
    auto ptr = source();
    sink(ptr);
    sink(std::move(ptr));
    auto p1 = source();
    auto p2 = p1;
    p2 = std::move(p1);
    p1 = p2;
    p1 = std::move(p2);
}

```

</div>

<div class="col">

```cpp
std::shared_ptr<MyData> source();
void sink(std::shared_ptr<MyData> ptr);

void collections() {
    std::vector<std::shared_ptr<MyData>> v;

    v.push_back(source());

    auto tmp = source();
    v.push_back(tmp);
    v.push_back(std::move(tmp));

    sink(v[0]);
    sink(std::move(v[0]));
}
```

</div>
</div>

___
<!-- .slide: style="font-size: 0.85em" -->

### `std::shared_ptr<>` usage (2)

```cpp
#include <memory>
#include <map>
#include <string>

class Gadget {};
std::map<std::string, std::shared_ptr<Gadget>> gadgets;

void foo() {
    std::shared_ptr<Gadget> p1{new Gadget()};   // reference counter = 1
    {
        auto p2 = p1;                           // copy (reference counter == 2)
        gadgets.insert(make_pair("mp3", p2));   // copy (reference counter == 3)
        p2->use();
    }                                           // destruction of p2, reference counter = 2
}                                               // destruction of p1, reference counter = 1

int main() {
    foo();
    gadgets.clear();                            // reference counter = 0 - gadget is removed
}
```
___

### Custom deleter

* <!-- .element: class="fragment fade-in" --> Don't change a type of <code>shared_ptr</code> because data is stored in control block
* <!-- .element: class="fragment fade-in" --> Don't change a size of <code>shared_ptr</code> because data is stored in control block
* <!-- .element: class="fragment fade-in" --> You can have a collection of <code>shared_ptr</code> which has different deleter

<div class="multicolumn">
<div class="col">

```C++
class Foo {};

void deleter1(Foo* const foo) {
    std::cout << "Deleter1\n";
    delete foo;
}

int main() {
    std::vector<std::shared_ptr<Foo>> vec;
    std::shared_ptr<Foo> ptr1(new Foo(), deleter1);
    vec.push_back(std::move(ptr1));

    auto deleter2 = [](Foo* const foo) { 
        std::cout << "Deleter2\n"; 
        delete foo; 
    };
    vec.emplace_back(new Foo(), deleter2);             
}
```
<!-- .element: class="fragment fade-in" -->
</div>

<div class="col">

```Bash
Deleter1
Deleter2
```
<!-- .element: class="fragment fade-in" -->
</div>

<!-- .slide: style="font-size: 0.8em" -->
___

### Problem with shared_ptr

Let's look at a short story:

* <!-- .element: class="fragment fade-in" --> Programmer1 : Why do you pass shared_ptr by copy? Passing by copy increment counter (slower then unique or raw ptr)
* <!-- .element: class="fragment fade-in" --> Programmer2: Ok, so I will pass it by const reference instead! And avoid unnecessary incrementation of the control block.
* <!-- .element: class="fragment fade-in" --> Programmer1: So if you don't need to copy it (don't need to have 2 owners) why don't use unique_ptr?
* <!-- .element: class="fragment fade-in" --> <b>Reassume</b>: shared_ptr should be use <b>only when given resource need to have few owners</b> (very rare situation). In other case use always unique_ptr!

___

### `std::shared_ptr<>` cyclic dependencies

* What happens here?

<div class="multicolumn" style="position: relative">
<div class="col" style="width: 65%; flex: none">

```cpp
#include <memory>

struct Node {
    std::shared_ptr<Node> child;
    std::shared_ptr<Node> parent;
};

int main () {
    auto root = std::shared_ptr<Node>(new Node);
    auto child = std::shared_ptr<Node>(new Node);

    root->child = child;
    child->parent = root;
}


```

</div>

<div class="col fragment fade-in">
    Memory leak!
    <img data-src="img/kot.jpg" alt="kot" class="plain" style="height: 50%">

</div>
