Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/uml/patterns_structural_flyweight.drawio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/core/basics/Operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void arithmeticOperator()

// Increment
cout << "a = " << a << "\n";
int preIn = ++a; // increase a, return copy
int preIn = ++a; // increase a, return a
cout << "preIn = " << preIn << "\n";

cout << "a = " << a << "\n";
Expand Down
40 changes: 40 additions & 0 deletions src/core/datatypes/CReferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,45 @@ void references()
std::cout << "By reference: " << b << '\n';
}

/**
*
a (lvalue)
|
| std::move(a) (rvalue reference)
V
source (rvalue reference parameter, but it's the lvalue inside the function)
|
| steal data
V
b
*/
namespace RvalueReference
{
using namespace std;

// Move-like function taking an rvalue reference as parameter
int copyConstructor(int &&x)
{
// Inside the function, x is a named lvalue that refers to the original object passed in (here, 'a')
int result = x * 10; // compute result based on x
x = 0; // reset the original object to 0
return result; // return the computed result
}

void run()
{
int a{10}; // original value

// Call function with an rvalue reference using std::move
// std::move(a) casts a (lvalue) into an rvalue reference (int&&)
int b = copyConstructor(std::move(a));

cout << b << endl; // prints 100
cout << a << endl; // prints 0, because x in the function referred to a and was reset
}

}

// A struct that runs code when its object is created
struct CReferences
{
Expand All @@ -58,6 +97,7 @@ struct CReferences
<< "Compound type: References\n";

references();
RvalueReference::run();
}
};

Expand Down
108 changes: 103 additions & 5 deletions src/core/datatypes/class/CConstructors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,14 @@ namespace Delegate
}

// *4. Copy constructor: initialize an copy object with an existing object
// Generated if no copy/move constructor or destructor is declared
// Generated if no copy/move constructor or `destructor` is declared
// Performs memberwise (shallow) copy
// * Copy constructor
// Object obj1 = obj2
// Object obj1(obj2)
// Object obj1{obj2}
// * Copy assigment
// obj1 = obj1
namespace Copy
{
class ICConstructor // C++ will create a public implicit copy constructor for us if we do not provide a one.
Expand Down Expand Up @@ -192,14 +198,27 @@ namespace Copy
cout << "Called ICConstructor(int x, int y) : m_x{x}, m_y{y} \n";
}

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

// Explicit Copy constructor (a=ECConstructor(b))
ECConstructor(const ECConstructor &ref) : m_x{ref.m_x}, m_y{ref.m_x}
{
cout << "Called ECConstructor(const ECConstructor& ref) : m_x{ref.m_x}, m_y{ref.m_x} \n";
}

// Copy assigment (a=b)
ECConstructor &operator=(const ECConstructor &other)
{
if (this != &other)
{
this->m_x = other.m_x;
this->m_y = other.m_y;
}
return *this;
}

void print() const
{
cout << "m_x = " << m_x << ", m_y = " << m_y << "\n";
Expand Down Expand Up @@ -246,12 +265,90 @@ namespace Copy
}
}

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

public:
Model(int x, int y) : m_x{x}, m_y{y}
{
cout << "Call constructor \n";
}

~Model()
{
cout << "Call destructor \n";
}

Model(const Model &other) : Model(other.m_x, other.m_y)
{
cout << "Call copy constructor \n";
}

Model &operator=(const Model &other)
{
cout << "Call copy assigment \n";
if (this != &other)
{
this->m_x = other.m_x;
this->m_y = other.m_y;
}
return *this;
}

Model(Model &&source) noexcept : m_x(source.m_x), m_y(source.m_y)
{
cout << "Call move constructor\n";

// reset source
source.m_x = 0;
source.m_y = 0;
}

Model &operator=(Model &&source) noexcept
{
cout << "Call move assigment \n";
if (this != &source)
{
this->m_x = source.m_x;
this->m_y = source.m_y;

// reset source
source.m_x = 0;
source.m_y = 0;
}

return *this;
}

void print() const
{
cout << "m_x = " << m_x << ", m_y = " << m_y << "\n";
}
};

void constructers()
{
cout << "\n--- Move Constructor Examples ---\n";
Model a(10, 20);

cout << "\nCase 1: Model b = std::move(a);\n";
Model b = std::move(a); // move constructor

cout << "\nCase 2: Model c(5,6); c = std::move(b);\n";
Model c(5, 6);
c = std::move(b); // move assignment
cout << "\n";
}
}

struct CConstructorsAutoRuner
Expand All @@ -262,6 +359,7 @@ struct CConstructorsAutoRuner
Default::constructers();
Delegate::constructors();
Copy::constructors();
Move::constructers();
}
};

Expand Down
10 changes: 7 additions & 3 deletions src/core/datatypes/class/SallowDeepCopying.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,14 @@ namespace

void deepCopy(const Model &source)
{
// first we need to deallocate any value that this Model is holding!
delete ptr;

// sallow copy the normal fields
m_x = source.m_x;
m_y = source.m_y;

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

// Copy constructor
// no need to check self-copy [if (this != &source)]
// because it cannot happen a(a);
Model(const Model &source)
{
this->deepCopy(source);
}

// Assignment operator
// need to check self-copy [if (this != &source)]
// because it posible a = a;
Model &operator=(const Model &source)
{
if (this != &source)
Expand Down
35 changes: 14 additions & 21 deletions src/patterns/structural/Composite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,10 @@ namespace

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

FileSystem *getParent() const
{
Expand Down Expand Up @@ -380,22 +383,21 @@ namespace
// Delete folder should delete all children
for (auto f : _children)
{
if (f != nullptr)
{
std::cout << "Folder '" << this->getName() << "' deleted : " << f->getName() << "\n";
delete f;
f = nullptr;
}
}
}

void add(FileSystem *fs) override
{
std::cout << "Folder '" << this->getName() << "' added : " << fs->getName() << "\n";
_children.push_back(fs);
fs->setParent(this);
}

void remove(FileSystem *fs) override
{
std::cout << "Folder: " << this->getName() << "removed : " << fs->getName() << "\n";
_children.remove(fs);
fs->setParent(nullptr);
}
Expand Down Expand Up @@ -511,23 +513,14 @@ namespace
root->add(subFolder3);
Client::clientCode(root);

// delete file1;
// file1 = nullptr;

// delete file2;
// file2 = nullptr;

// delete file3;
// file3 = nullptr;

// delete subFolder1;
// subFolder1 = nullptr;
root->remove(file1);
delete file1;

// delete subFolder2;
// subFolder2 = nullptr;
root->remove(file2);
delete file2;

// delete subFolder3;
// subFolder3 = nullptr;
root->remove(file3);
delete file3;

delete root; // deletes all files/subfolders inside recursively
}
Expand All @@ -541,7 +534,7 @@ struct CompositeAutoRuner
CompositeAutoRuner()
{
std::cout << "\n--- Composite Pattern Example ---\n";
Problem::run();
// Problem::run();
CompositePattern::run();
}
};
Expand Down
Loading