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

# `std::unique_ptr<>`

___

## `std::unique_ptr<>`

<div>

* <!-- .element: class="fragment fade-in" --> one object == one owner
* <!-- .element: class="fragment fade-in" --> destructor destroys the object
* <!-- .element: class="fragment fade-in" --> copying not allowed
* <!-- .element: class="fragment fade-in" --> moving allowed
* <!-- .element: class="fragment fade-in" --> can use custom deleter
* <!-- .element: class="fragment fade-in" --> <a href="https://quick-bench.com/q/kZs8qerce1or9_0R0QNezh_hVM4" target="_top">0 cost class -> no impact on efficiency</a>

</div>

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

___

### `std::unique_ptr<>` usage

* Old style approach vs modern approach

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

```cpp
#include <iostream> // old-style approach


struct Msg {
    int getValue() { return 42; }
};

Msg* createMsg() {
    return new Msg{};
}

int main() {
    auto msg = createMsg();

    std::cout << msg->getValue();
    delete msg;
}
```
<!-- .element: class="fragment fade-in" -->

</div>

<div class="col">

```cpp
#include <memory> // modern approach
#include <iostream>

struct Msg {
    int getValue() { return 42; }
};

std::unique_ptr<Msg> createMsg() {
    return std::make_unique<Msg>();
}

int main() {
    // unique ownership
    auto msg = createMsg();

    std::cout << msg->getValue();
}

```
<!-- .element: class="fragment fade-in" -->

</div>

___

### `std::unique_ptr<>` usage

* <!-- .element: class="fragment fade-in" --> Copying is not allowed
* <!-- .element: class="fragment fade-in" --> Moving is allowed

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

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

void simpleUsage() {
    source();
    sink(source());
    auto ptr = source();
    // sink(ptr);       // compilation error
    sink(std::move(ptr));
    auto p1 = source();
    // auto p2 = p1;    // compilation error
    auto p2 = std::move(p1);
    // p1 = p2;         // compilation error
    p1 = std::move(p2);
}
```
<!-- .element: class="fragment fade-in" -->

</div>

<div class="col">

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

void collections() {
    std::vector<std::unique_ptr<MyData>> v;
    v.push_back(source());

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

    // sink(v[0]);       // compilation error
    sink(std::move(v[0]));

}
```
<!-- .element: class="fragment fade-in" -->

</div>

___

#### `std::unique_ptr<>` problem with containers

<div class="col">

<!-- .element: class="fragment fade-in" --> What is wrong with this part of code?

<!-- .element: class="fragment fade-in" -->
```cpp
std::unique_ptr<MyData> source(void);
void sink(std::unique_ptr<MyData> ptr);

void collections() {
    std::vector<std::unique_ptr<MyData>> v;
    v.push_back(source());

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

    sink(std::move(v[0]));
    std::cout << *(v[0]) << '\n';
}
```

</div>

___

#### `std::unique_ptr<>` cooperation with raw pointers

```cpp
#include <memory>

void legacyInterface(int*) {}
void deleteResource(int* p) { delete p; }
void referenceInterface(int&) {}

int main() {
    auto ptr = std::make_unique<int>(5);
    legacyInterface(ptr.get());
    deleteResource(ptr.release());
    ptr.reset(new int{10});
    referenceInterface(*ptr);
    ptr.reset(); // ptr is a nullptr
    return 0;
}
```

* <!-- .element: class="fragment fade-in" --> <code>get()</code> – returns a raw pointer without releasing the ownership
* <!-- .element: class="fragment fade-in" --> <code>release()</code> – returns a raw pointer and release the ownership
* <!-- .element: class="fragment fade-in" --> <code>reset()</code> – replaces the manager object
* <!-- .element: class="fragment fade-in" --> <code>operator*()</code> – dereferences pointer to the managed object

___

### `std::make_unique()`

```cpp
#include <memory>

struct Msg {
    Msg(int i) : value(i) {}
    int value;
};

int main() {
    auto ptr1 = std::unique_ptr<Msg>(new Msg{5});
    auto ptr2 = std::make_unique<Msg>(5);   // equivalent to above
    return 0;
}
```

`std::make_unique()` is a factory function that produce `unique_ptrs`
<!-- .element: class="fragment fade-in" -->

* <!-- .element: class="fragment fade-in" --> added in C++14 for symmetrical operations on unique and shared pointers
* <!-- .element: class="fragment fade-in" --> avoids bare <code>new</code> expression

___

### `std::unique_ptr<T[]>`

```cpp
struct MyData {};

void processPointer(MyData* md) {}
void processElement(MyData md) {}

using Array = std::unique_ptr<MyData[]>;

void use(void)
{
    Array tab{new MyData[42]};
    processPointer(tab.get());  
    processElement(tab[13]);
}
```

* <!-- .element: class="fragment fade-in" --> During destruction
  * <!-- .element: class="fragment fade-in" --> <code>std::unique_ptr&ltT&gt</code> calls <code>delete</code>
  * <!-- .element: class="fragment fade-in" --> <code>std::unique_ptr&ltT[]&gt</code> calls <code>delete[]</code>
* <!-- .element: class="fragment fade-in" --> <code>std::unique_ptr&ltT[]&gt</code> has additional <code>operator[]</code> for accessing array element
* <!-- .element: class="fragment fade-in" --> Usually <code>std::vector&ltT&gt</code> is a better choice

___

## Exercise: Resource

1. <!-- .element: class="fragment fade-in" --> Compile and run Resource application
2. <!-- .element: class="fragment fade-in" --> Check memory leaks under valgrind
3. <!-- .element: class="fragment fade-in" --> Fix memory leaks with a proper usage of <code>delete</code> operator
4. <!-- .element: class="fragment fade-in" --> Refactor the solution to use <code>std::unique_ptr<></code>
5. <!-- .element: class="fragment fade-in" --> Use <code>std::make_unique()</code>

___

## Exercise: Converter

1.  <!-- .element: class="fragment fade-in" --> Compile and run Converter application and check memory leaks under valgrind
2.  <!-- .element: class="fragment fade-in" --> Fix code using std::unique_ptr and std::make_unique
3.  <!-- .element: class="fragment fade-in" --> Find other issues and fix them (use good practise etc...)

___

## Why virtual D'tor is so important (1)?

```C++
class Resource {
public:
    explicit Resource(const std::string& str): str_(str) {}

    const std::string& str() const {
        return str_;
    }

private:
    std::string str_;
};

class Converter {
public:
    Converter() {
         std::cout << "C'tor converter\n";
    }

    virtual ~Converter() {
         std::cout << "D'tor converter\n";
    }

    virtual void Convert(const std::unique_ptr<Resource>& resource) const = 0;
};

class CurlyBracketConverter : public Converter {
public:
    CurlyBracketConverter() {
         std::cout << "C'tor CurlyBracketConverter\n";
    }

    ~CurlyBracketConverter() override {
        std::cout << "D'tor CurlyBracketConverter\n";
    }

    void Convert(const std::unique_ptr<Resource>& resource) const override {
        std::cout << "{" << resource->str() << "}\n";
    }
};

class SquareBracketConverter : public Converter {
public:
    SquareBracketConverter() {
         std::cout << "C'tor SquareBracketConverter\n";
    }

    ~SquareBracketConverter() override {
        std::cout << "D'tor SquareBracketConverter\n";
    }

    virtual void Convert(const std::unique_ptr<Resource>& resource) const override{
        std::cout << "[" << resource->str() << "]\n";
    }
};

class Printer {
public:
    explicit Printer(std::unique_ptr<Converter> converter): converter_(std::move(converter)) {}

    void Print(const std::unique_ptr<Resource>& resource) const {
        converter_->Convert(resource);
    }

private:
    std::unique_ptr<Converter> converter_;
};

int main() {
    auto resource = std::make_unique<Resource>("Ala has a cat");
    Printer printer(std::make_unique<SquareBracketConverter>());
    Printer printer2(std::make_unique<CurlyBracketConverter>());

    return 0;
}
```
<!-- .element: style="font-size: 0.8rem" -->

___

## Why virtual D'tor is so important (2)?

```C++
C'tor converter
C'tor SquareBracketConverter
C'tor converter
C'tor CurlyBracketConverter
D'tor converter
D'tor converter
```
<!-- .element: style="font-size: 1.2rem" -->

<!-- .element: class="fragment fade-in" --> 

Try to add virtual to your D'tor and check result

<!-- .element: class="fragment fade-in" --> 

```C++
C'tor converter
C'tor SquareBracketConverter
C'tor converter
C'tor CurlyBracketConverter
D'tor CurlyBracketConverter
D'tor converter
D'tor SquareBracketConverter
D'tor converter
```
<!-- .element: class="fragment fade-in" --> 

___

## Custom Deleter

* <!-- .element: class="fragment fade-in" --> When there is a special way to delete object
* <!-- .element: class="fragment fade-in" --> Type of unique_ptr change!

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

```C++
class Foo {
public:
    Foo() {
        std::cout << "Foo C'tor\n";
    }

    void print() const {
        std::cout << "Foo!\n";
    }

private:
    // For some reason, we allow only this function to delete object
    friend void deleteMe(Foo* const foo);

    ~Foo() {
        std::cout << "Foo D'tor\n";
    }
};

void deleteMe(Foo* const foo) {
    std::cout << "Delete object Foo!\n";
    delete foo;
}

int main() {
    // Can't use make unique, need to use unique_ptr C'tor
    // unique_ptr(pointer __p, const deleter_type& __d) noexcept
    std::unique_ptr<Foo, void(*)(Foo* const)> ptr(new Foo, deleteMe);
    ptr->print();

    return 0;
}

```
<!-- .element: style="font-size: 0.8rem" -->
<!-- .element: class="fragment fade-in" -->

</div>

<div class="col">

<!-- .element: class="fragment fade-in" --> Output

```C++
Foo C'tor
Foo!
Delete object Foo!
Foo D'tor
```

<!-- .element: class="fragment fade-in" -->

</div>
