Skip to content

Commit

Permalink
Add unique_ptr video
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesmurphy-mc committed Apr 11, 2023
1 parent 9560806 commit ba22906
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ James and his team are available for consulting, contracting, code reviews, and

| N | Code | Video |
| -- | --- |--- |
| 121 | [src](videos/121_unique_ptr) | [unique_ptr: C++'s simplest smart pointer](https://youtu.be/AmjoK55h68Y) |
| 120 | [src](videos/120_python_ternary_operator) | [Does Python have a ternary operator?](https://youtu.be/zjwhh2MEa0Q) |
| 119 | [src](videos/119_more_nooby_python_habits) | [21 MORE nooby Python habits](https://youtu.be/E8NijUYfyus) |
| 118 | [src](videos/118_strings_and_bytes) | [str vs bytes in Python](https://youtu.be/EimoZHDcQMA) |
Expand Down
5 changes: 5 additions & 0 deletions videos/121_unique_ptr/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
BasedOnStyle: Google
IndentWidth: 4
---

10 changes: 10 additions & 0 deletions videos/121_unique_ptr/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.16...3.23)

project(UNIQUE_PTR_EXAMPLE)

add_executable(main main.cpp)
set_target_properties(
main PROPERTIES
CXX_STANDARD 20
CXX_EXTENSIONS OFF
)
131 changes: 131 additions & 0 deletions videos/121_unique_ptr/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#include <iostream>
#include <memory>
#include <utility>
#include <vector>

template <class T>
class unique_ptr {
public:
unique_ptr() noexcept : unique_ptr{nullptr} {}
explicit unique_ptr(T *ptr) noexcept : m_ptr{ptr} {}

unique_ptr(const unique_ptr &) = delete;
unique_ptr &operator=(const unique_ptr &) = delete;

unique_ptr(unique_ptr &&other) noexcept : m_ptr{other.release()} {}

unique_ptr &operator=(unique_ptr &&other) noexcept {
if (this != &other) {
reset(other.release());
}
return *this;
}

explicit operator bool() const noexcept { return static_cast<bool>(m_ptr); }

T *get() const noexcept { return m_ptr; }
T *operator->() const noexcept { return m_ptr; }
T &operator*() const noexcept { return *m_ptr; }

T *release() noexcept { return std::exchange(m_ptr, nullptr); }

void reset(T *ptr = nullptr) noexcept {
T *old = std::exchange(m_ptr, ptr);
if (old) {
delete old;
}
}

~unique_ptr() noexcept {
if (m_ptr) {
delete m_ptr;
}
}

private:
T *m_ptr;
};

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

struct Widget {
int val;

explicit Widget(int val) : val{val} {
std::cout << "ctor: " << val << '\n';
}

virtual ~Widget() noexcept { std::cout << "dtor: " << val << '\n'; }
};

void use_widget(const Widget *w) {
std::cout << "yep, that's a widget: " << w->val << '\n';
}

void use_widget(const Widget &w) {
std::cout << "yep, that's a widget: " << w.val << '\n';
}

void vector_raw_example() {
std::vector<Widget *> widgets;
const std::size_t count = 5;
widgets.reserve(count);
for (std::size_t i = 0; i < count; ++i) {
widgets.push_back(new Widget(i));
}

for (const auto &widget : widgets) {
use_widget(widget);
}

delete widgets.back();
widgets.pop_back();

Widget *last = widgets.back();
widgets.pop_back();

std::cout << "last element was " << last->val << '\n';

delete last;

for (std::size_t i = 0; i < widgets.size(); ++i) {
delete widgets[i];
}
}

void vector_example() {
std::vector<unique_ptr<Widget>> widgets;
const std::size_t count = 5;
widgets.reserve(count);
for (std::size_t i = 0; i < count; ++i) {
widgets.push_back(unique_ptr<Widget>(new Widget(i)));
// widgets.push_back(make_unique<Widget>(i));
}

for (const auto &widget : widgets) {
use_widget(widget.get());
use_widget(*widget);
}

widgets.pop_back(); // automatically deleted

unique_ptr<Widget> last = std::move(widgets.back());
widgets.pop_back();

std::cout << "last element was " << last->val << '\n';
}

int main() {
int *xp = new int(42);
*xp = 0;
delete xp;

auto yp = std::make_unique<int>(42);
*yp = 0;

vector_example();
return 0;
}

0 comments on commit ba22906

Please sign in to comment.