C++ Library Extensions 2022.12.09
To help learn modern C++ programming
02-unique_ptr.cpp
Go to the documentation of this file.
1#include <tpf_output.hpp>
2
5
6/*
7 We will learn how to pass unique_ptr by reference.
8 Then, we will learn how to return unique_ptr from a function,
9 then from a member function of a class.
10 */
11
12void take_unique_ptr_by_reference(const std::unique_ptr<int>& ptr)
13{
14 stream << "The value of the object the ptr is pointing to = " << *ptr << endl;
15}
16
18{
19 auto ptr = std::make_unique<int>(10);
20
21 // we are passing unique_ptr ptr to a function by reference
23
24 // since we passed ptr by reference,
25 // ptr is still valued.
26
27 if(ptr)
28 {
29 stream << "Ptr is still valid: " << *ptr << endl;
30 }
31 else
32 {
33 stream << "Ptr is invalid" << endl;
34 }
35}
36
38{
39 public:
40 std::unique_ptr<int> m_ptr;
41
42 public:
43
44 DummyClass(int value = 0):
45 m_ptr{ std::make_unique<int>(value) } { }
46
47 // this function returns reference to a member unique_ptr
48 const std::unique_ptr<int>& return_unique_ptr_reference()
49 {
50 // since we are returning reference to m_ptr
51 // this->m_ptr is valid after this function returns
52 return this->m_ptr;
53 }
54
55 // this function returns class member unique_ptr
56 std::unique_ptr<int> return_unique_ptr_of_member_data()
57 {
58 // this does not work
59 // return this->m_ptr;
60
61 // we are returning the ownership of
62 // this->m_ptr, after this call
63 // this->m_ptr is invalid
64 return std::move(this->m_ptr);
65
66 // WARNING: after move, this->m_ptr is invalid
67 }
68
69 // returns local instance of unique_ptr
70 // this function returns local instance of
71 // unique_ptr
72 std::unique_ptr<int> return_unique_ptr(int value)
73 {
74 auto ptr = std::make_unique<int>(value);
75
76 return ptr;
77 }
78
79};
80
82{
83 DummyClass dummy{10};
84
85 // constness is preserved
86
87 auto& ptr1 = dummy.return_unique_ptr_reference();
88
89 decltype(auto) ptr2 = dummy.return_unique_ptr_reference();
90
91 stream <<"The type of ptr1: "
92 << Tpf_GetTypeCategory(ptr1) << endl;
93
94 stream << "The value of ptr1: "
95 << *ptr1 << endl;
96
97 stream <<"The type of ptr2: "
98 << Tpf_GetTypeCategory(ptr2) << endl;
99
100 stream << "The value of ptr2: "
101 << *ptr2 << endl;
102}
103
104std::unique_ptr<int> make_int_ptr(int value)
105{
106 auto ptr = std::make_unique<int>(value);
107 return ptr;
108}
109
110// never do this, this does not work
111// it does not work. You are causing trouble by returning local variable
112std::unique_ptr<int>&& return_rvalue_ref_unique_ptr(int value)
113{
114 auto ptr = std::make_unique<int>(value);
115
116 return std::move(ptr); // std::move(ptr) is not the cause the problem.
117}
118
120{
121 DummyClass dummy{10};
122
123 auto ptr = dummy.return_unique_ptr(10);
124
125 stream <<"the value of the object ptr is pointing to: "
126 << *ptr << endl;
127}
128
130{
131 DummyClass dummy{10};
132
133 // return_unique_ptr_of_member_data()
134 // moves the ownership of m_ptr to ptr
135 // after this call, dummy.m_ptr is invalid
136 auto ptr = dummy.return_unique_ptr_of_member_data();
137
138 stream << "the value of the object ptr is pointing to: "
139 << *ptr << endl;
140
141 if(dummy.m_ptr)
142 {
143 stream << "dummy.m_ptr is still valid: "
144 << *dummy.m_ptr << endl;
145 }
146 else
147 {
148 stream <<"dummy.m_ptr is invalid" << endl;
149 }
150
151}
152
153// never do this, this does not work
154// it does not work. You are causing trouble by returning local variable
155// std::unique_ptr<int>& return_lvalue_ref_unique_ptr(int value)
156// {
157// auto ptr = std::make_unique<int>(value);
158
159// return std::move(ptr); // std::move(ptr) is not the cause the problem.
160// }
161
162
164{
165 auto p = make_int_ptr(20);
166
167 stream <<"The value of the object the ptr p is pointing to: "
168 << *p << endl;
169}
170
172{
173 auto p = return_rvalue_ref_unique_ptr(10);
174
175 stream <<"*p is " << *p << endl;
176}
177
178// void cause_of_trouble_with_reference()
179// {
180// auto& p = return_lvalue_ref_unique_ptr(10);
181
182// stream <<"*p is " << *p << endl;
183// }
184
185int main()
186{
187 // test_pass_unique_ptr_by_reference();
188
189 // get_unique_ptr_from_a_function();
190
191 // cause_of_trouble();
192
193 // cause_of_trouble_with_reference();
194
195 // test_member_function_returning_unique_ptr();
196
197 // test_member_function_returning_member_unique_ptr();
198
200}
void test_member_function_returning_member_unique_ptr()
void get_unique_ptr_from_a_function()
std::unique_ptr< int > make_int_ptr(int value)
tpf::sstream stream
void test_member_function_returning_unique_ptr()
void take_unique_ptr_by_reference(const std::unique_ptr< int > &ptr)
void test_return_unique_ptr_reference()
auto endl
void test_pass_unique_ptr_by_reference()
int main()
void cause_of_trouble()
std::unique_ptr< int > && return_rvalue_ref_unique_ptr(int value)
std::unique_ptr< int > m_ptr
std::unique_ptr< int > return_unique_ptr(int value)
DummyClass(int value=0)
std::unique_ptr< int > return_unique_ptr_of_member_data()
const std::unique_ptr< int > & return_unique_ptr_reference()
constexpr auto endl
Definition: tpf_output.hpp:973
Stream output operators << are implemented.
#define Tpf_GetTypeCategory(instance_arg)
A macro that returns instance_arg's type category string name.
Definition: tpf_types.hpp:1428