-
Notifications
You must be signed in to change notification settings - Fork 206
/
main.cpp
131 lines (100 loc) · 2.96 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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;
}