Skip to content

Commit 8abda8b

Browse files
authored
Merge pull request #12 from urboob21/dev_branch
id 1763269269
2 parents b54f50d + 92d93f6 commit 8abda8b

File tree

7 files changed

+317
-59
lines changed

7 files changed

+317
-59
lines changed

docs/uml/patterns_structural_flyweight.drawio.svg

Lines changed: 4 additions & 0 deletions
Loading

src/core/basics/Operations.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void arithmeticOperator()
5252

5353
// Increment
5454
cout << "a = " << a << "\n";
55-
int preIn = ++a; // increase a, return copy
55+
int preIn = ++a; // increase a, return a
5656
cout << "preIn = " << preIn << "\n";
5757

5858
cout << "a = " << a << "\n";

src/core/datatypes/CReferences.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,45 @@ void references()
4848
std::cout << "By reference: " << b << '\n';
4949
}
5050

51+
/**
52+
*
53+
a (lvalue)
54+
|
55+
| std::move(a) (rvalue reference)
56+
V
57+
source (rvalue reference parameter, but it's the lvalue inside the function)
58+
|
59+
| steal data
60+
V
61+
b
62+
*/
63+
namespace RvalueReference
64+
{
65+
using namespace std;
66+
67+
// Move-like function taking an rvalue reference as parameter
68+
int copyConstructor(int &&x)
69+
{
70+
// Inside the function, x is a named lvalue that refers to the original object passed in (here, 'a')
71+
int result = x * 10; // compute result based on x
72+
x = 0; // reset the original object to 0
73+
return result; // return the computed result
74+
}
75+
76+
void run()
77+
{
78+
int a{10}; // original value
79+
80+
// Call function with an rvalue reference using std::move
81+
// std::move(a) casts a (lvalue) into an rvalue reference (int&&)
82+
int b = copyConstructor(std::move(a));
83+
84+
cout << b << endl; // prints 100
85+
cout << a << endl; // prints 0, because x in the function referred to a and was reset
86+
}
87+
88+
}
89+
5190
// A struct that runs code when its object is created
5291
struct CReferences
5392
{
@@ -58,6 +97,7 @@ struct CReferences
5897
<< "Compound type: References\n";
5998

6099
references();
100+
RvalueReference::run();
61101
}
62102
};
63103

src/core/datatypes/class/CConstructors.cpp

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,14 @@ namespace Delegate
158158
}
159159

160160
// *4. Copy constructor: initialize an copy object with an existing object
161-
// Generated if no copy/move constructor or destructor is declared
161+
// Generated if no copy/move constructor or `destructor` is declared
162162
// Performs memberwise (shallow) copy
163+
// * Copy constructor
164+
// Object obj1 = obj2
165+
// Object obj1(obj2)
166+
// Object obj1{obj2}
167+
// * Copy assigment
168+
// obj1 = obj1
163169
namespace Copy
164170
{
165171
class ICConstructor // C++ will create a public implicit copy constructor for us if we do not provide a one.
@@ -192,14 +198,27 @@ namespace Copy
192198
cout << "Called ICConstructor(int x, int y) : m_x{x}, m_y{y} \n";
193199
}
194200

201+
// Implicit Copy constructor if there is no desconstrutor
195202
// using `default` keyword
196203
// ECConstructor(const ECConstructor &ref) = default;
197204

205+
// Explicit Copy constructor (a=ECConstructor(b))
198206
ECConstructor(const ECConstructor &ref) : m_x{ref.m_x}, m_y{ref.m_x}
199207
{
200208
cout << "Called ECConstructor(const ECConstructor& ref) : m_x{ref.m_x}, m_y{ref.m_x} \n";
201209
}
202210

211+
// Copy assigment (a=b)
212+
ECConstructor &operator=(const ECConstructor &other)
213+
{
214+
if (this != &other)
215+
{
216+
this->m_x = other.m_x;
217+
this->m_y = other.m_y;
218+
}
219+
return *this;
220+
}
221+
203222
void print() const
204223
{
205224
cout << "m_x = " << m_x << ", m_y = " << m_y << "\n";
@@ -246,12 +265,90 @@ namespace Copy
246265
}
247266
}
248267

249-
// *4. Copy constructor: initialize an copy object with an existing object
250-
// Generated if no copy/move constructor or destructor is declared
251-
// Performs memberwise (shallow) copy
252-
namespace Copy
268+
// *4. Move Constructor:
269+
// Move constructor and move assignment transfer resource ownership
270+
// from one object to another. This is usually cheaper than copying.
271+
// A move constructor is implicitly generated only if no user-declared
272+
// copy constructor, move constructor, or destructor exists.
273+
namespace Move
253274
{
275+
class Model // C++ will create a public implicit copy constructor for us if we do not provide a one.
276+
{
277+
private:
278+
int m_x;
279+
int m_y;
254280

281+
public:
282+
Model(int x, int y) : m_x{x}, m_y{y}
283+
{
284+
cout << "Call constructor \n";
285+
}
286+
287+
~Model()
288+
{
289+
cout << "Call destructor \n";
290+
}
291+
292+
Model(const Model &other) : Model(other.m_x, other.m_y)
293+
{
294+
cout << "Call copy constructor \n";
295+
}
296+
297+
Model &operator=(const Model &other)
298+
{
299+
cout << "Call copy assigment \n";
300+
if (this != &other)
301+
{
302+
this->m_x = other.m_x;
303+
this->m_y = other.m_y;
304+
}
305+
return *this;
306+
}
307+
308+
Model(Model &&source) noexcept : m_x(source.m_x), m_y(source.m_y)
309+
{
310+
cout << "Call move constructor\n";
311+
312+
// reset source
313+
source.m_x = 0;
314+
source.m_y = 0;
315+
}
316+
317+
Model &operator=(Model &&source) noexcept
318+
{
319+
cout << "Call move assigment \n";
320+
if (this != &source)
321+
{
322+
this->m_x = source.m_x;
323+
this->m_y = source.m_y;
324+
325+
// reset source
326+
source.m_x = 0;
327+
source.m_y = 0;
328+
}
329+
330+
return *this;
331+
}
332+
333+
void print() const
334+
{
335+
cout << "m_x = " << m_x << ", m_y = " << m_y << "\n";
336+
}
337+
};
338+
339+
void constructers()
340+
{
341+
cout << "\n--- Move Constructor Examples ---\n";
342+
Model a(10, 20);
343+
344+
cout << "\nCase 1: Model b = std::move(a);\n";
345+
Model b = std::move(a); // move constructor
346+
347+
cout << "\nCase 2: Model c(5,6); c = std::move(b);\n";
348+
Model c(5, 6);
349+
c = std::move(b); // move assignment
350+
cout << "\n";
351+
}
255352
}
256353

257354
struct CConstructorsAutoRuner
@@ -262,6 +359,7 @@ struct CConstructorsAutoRuner
262359
Default::constructers();
263360
Delegate::constructors();
264361
Copy::constructors();
362+
Move::constructers();
265363
}
266364
};
267365

src/core/datatypes/class/SallowDeepCopying.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,14 @@ namespace
9292

9393
void deepCopy(const Model &source)
9494
{
95-
// first we need to deallocate any value that this Model is holding!
96-
delete ptr;
97-
9895
// sallow copy the normal fields
9996
m_x = source.m_x;
10097
m_y = source.m_y;
10198

99+
// deep copy the ptr field
102100
// m_data is a pointer, so we need to deep copy it if it is non-null
101+
// first we need to deallocate any value that this Model is holding!
102+
delete ptr;
103103
if (source.ptr != nullptr)
104104
{
105105
// allocate memory for our copy
@@ -128,12 +128,16 @@ namespace
128128
}
129129

130130
// Copy constructor
131+
// no need to check self-copy [if (this != &source)]
132+
// because it cannot happen a(a);
131133
Model(const Model &source)
132134
{
133135
this->deepCopy(source);
134136
}
135137

136138
// Assignment operator
139+
// need to check self-copy [if (this != &source)]
140+
// because it posible a = a;
137141
Model &operator=(const Model &source)
138142
{
139143
if (this != &source)

src/patterns/structural/Composite.cpp

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,10 @@ namespace
267267

268268
public:
269269
explicit FileSystem(const std::string &fileName) : _parent{nullptr}, _name{fileName} {}
270-
virtual ~FileSystem() = default;
270+
virtual ~FileSystem()
271+
{
272+
std::cout << "Destructor: " << this->getName() << "\n";
273+
}
271274

272275
FileSystem *getParent() const
273276
{
@@ -380,22 +383,21 @@ namespace
380383
// Delete folder should delete all children
381384
for (auto f : _children)
382385
{
383-
if (f != nullptr)
384-
{
386+
std::cout << "Folder '" << this->getName() << "' deleted : " << f->getName() << "\n";
385387
delete f;
386-
f = nullptr;
387-
}
388388
}
389389
}
390390

391391
void add(FileSystem *fs) override
392392
{
393+
std::cout << "Folder '" << this->getName() << "' added : " << fs->getName() << "\n";
393394
_children.push_back(fs);
394395
fs->setParent(this);
395396
}
396397

397398
void remove(FileSystem *fs) override
398399
{
400+
std::cout << "Folder: " << this->getName() << "removed : " << fs->getName() << "\n";
399401
_children.remove(fs);
400402
fs->setParent(nullptr);
401403
}
@@ -511,23 +513,14 @@ namespace
511513
root->add(subFolder3);
512514
Client::clientCode(root);
513515

514-
// delete file1;
515-
// file1 = nullptr;
516-
517-
// delete file2;
518-
// file2 = nullptr;
519-
520-
// delete file3;
521-
// file3 = nullptr;
522-
523-
// delete subFolder1;
524-
// subFolder1 = nullptr;
516+
root->remove(file1);
517+
delete file1;
525518

526-
// delete subFolder2;
527-
// subFolder2 = nullptr;
519+
root->remove(file2);
520+
delete file2;
528521

529-
// delete subFolder3;
530-
// subFolder3 = nullptr;
522+
root->remove(file3);
523+
delete file3;
531524

532525
delete root; // deletes all files/subfolders inside recursively
533526
}
@@ -541,7 +534,7 @@ struct CompositeAutoRuner
541534
CompositeAutoRuner()
542535
{
543536
std::cout << "\n--- Composite Pattern Example ---\n";
544-
Problem::run();
537+
// Problem::run();
545538
CompositePattern::run();
546539
}
547540
};

0 commit comments

Comments
 (0)