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
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ set(APP_SOURCES
"src/core/datatypes/CStruct.cpp"
"src/core/datatypes/CUnion.cpp"
"src/core/datatypes/TypeConVersions.cpp"
"src/core/datatypes/class/CConstructors.cpp"
"src/core/datatypes/class/CDestructors.cpp"
"src/patterns/structural/Adapter.cpp"
)

# Test files
Expand Down
4 changes: 4 additions & 0 deletions docs/uml/patterns_structural_adapter.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/InitializeVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct Foo
cout << "Default constructor/ default init\n";
}

// explicit Foo(int)
// Foo(int)
explicit Foo(int)
{
cout << "Constructor called with int / copy init\n";
Expand Down
254 changes: 254 additions & 0 deletions src/core/datatypes/class/CConstructors.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
#include <iostream>
using namespace std;

// *1. Members initializer list constructor
namespace InitializerList
{
class CConstructors
{
private:
int m_x, m_y, m_z;

public:
CConstructors(int x, int y) : m_x(x), m_y(y)
{
cout << "Called CConstructors(int x, int y) : m_x(x), m_y(y) \n";
// m_z{0}; // error, it already initialized, so only can do assigment
// m_z(0); // error, it already initialized, so only can do assigment
m_z = 0;
}

// using brace init
CConstructors(int x, int y, int z) : m_x{x}, m_y{y}, m_z{z}
{
cout << "Called CConstructors(int x, int y, int z) : m_x{x}, m_y{y}, m_z{z} \n";
}

// default arguments : must always be the RIGHTMOST parameters
explicit CConstructors(int x = 1)
{
cout << "Called CConstructors(int x = 1) \n";
m_x = x;
m_y = 0;
m_z = 0;
}

// CConstructors() = default; error:
// ‘InitializerList::CConstructors::CConstructors(int)’ cannot be overloaded with
// ‘InitializerList::CConstructors::CConstructors(int x = 1)’

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

void constructers()
{
cout << "\n--- InitializerList Constructer Examples ---\n";
CConstructors obj;
CConstructors obj1 = CConstructors(1, 2);
obj1.print();

CConstructors obj2 = CConstructors(3, 4, 5);
obj2.print();
}
}

// *2. Default constructor: is a constructor that accepts no arguments.
namespace Default
{
class UConstructors
{
public:
// User-defined default constructor without argument
UConstructors()
{
cout << "Called UConstructors() \n";
}
};

class IConstructors
{
public:
// Implicit default constructor is generated by the compiler when the class has no user-declared constructors
};

class EConstructors
{
public:
// we already create the constructor ourselves
// EConstructors(int a)
explicit EConstructors(float a) // explicit -> [[maybe_unused]] EConstructors obj2 = 1; [ERROR]

{
cout << "Called explicit EConstructors(int a) \n";
}

// Explicit default constructor : also want the compiler to generate the default constructor.
EConstructors() = default;
};

void constructers()
{
cout << "\n--- Default Constructer Examples ---\n";
[[maybe_unused]] UConstructors obj1;
// [[maybe_unused]] UConstructors obj2(); // wrong, this is function declare
// FYI:
// void outer()
// {
// void helper();
// helper(); // defined later in the same file
// }

[[maybe_unused]] UConstructors obj3{};

[[maybe_unused]] IConstructors obj4;
[[maybe_unused]] IConstructors obj6{};

[[maybe_unused]] EConstructors obj7;
[[maybe_unused]] EConstructors obj9{};

[[maybe_unused]] EConstructors obj10(1.2);
[[maybe_unused]] EConstructors obj11{2};
}
}

// *3. Delegate constructor: allow to delegate initialization to another constructor
namespace Delegate
{
class CConstructor
{
private:
int m_x;
int m_y;

public:
CConstructor(int x, int y) : m_x{x}, m_y{y}
{
cout << "Called CConstructor(int x, int y) : m_x{x}, m_y{y} \n";
}

explicit CConstructor(int x) : CConstructor{x, 1}
{
cout << "Called CConstructor(int x):CConstructor(x,0) \n";
}

CConstructor() : CConstructor(0)
{
cout << "Called CConstructor() : CConstructor(0) \n";
}

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

void constructors()
{
cout << "\n--- Delegate Constructer Examples ---\n";
CConstructor obj1 = CConstructor();
obj1.print();
}
}

// *4. Copy constructor: initialize an copy object with an existing object
namespace Copy
{
class ICConstructor // 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:
ICConstructor(int x, int y) : m_x{x}, m_y{y}
{
cout << "Called ICConstructor(int x, int y) : m_x{x}, m_y{y} \n";
}

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

class ECConstructor // explicitly define our own copy constructor
{
private:
int m_x;
int m_y;

public:
ECConstructor(int x, int y) : m_x{x}, m_y{y}
{
cout << "Called ICConstructor(int x, int y) : m_x{x}, m_y{y} \n";
}

// using `default` keyword
// ECConstructor(const ECConstructor &ref) = default;

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";
}

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

class DECConstructor // Delete the copy constructor so no copies can be made
{
private:
int m_x;
int m_y;

public:
DECConstructor(int x, int y) : m_x{x}, m_y{y}
{
cout << "Called DECConstructor(int x, int y) : m_x{x}, m_y{y} \n";
}

// using `delete` keyword
DECConstructor(const DECConstructor &fraction) = delete;

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

void constructors()
{
cout << "\n--- Copy Constructer Examples ---\n";
ICConstructor obj1 = ICConstructor(1, 2);
ICConstructor obj2{obj1};
obj1.print();
obj2.print();

ECConstructor obj3 = ECConstructor(3, 4);
ECConstructor obj4{obj3};
obj3.print();
obj4.print();

DECConstructor obj5 = DECConstructor(5, 6);
// DECConstructor obj6{obj5}; error
obj5.print();
}
}

struct CConstructorsAutoRuner
{
CConstructorsAutoRuner()
{
InitializerList::constructers();
Default::constructers();
Delegate::constructors();
Copy::constructors();
}
};

static CConstructorsAutoRuner instance;
90 changes: 90 additions & 0 deletions src/core/datatypes/class/CDestructors.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include <iostream>
using namespace std;

// *1. Basic Destructor
namespace Basic
{
class CDestructors
{
public:
CDestructors()
{
cout << "Called CDestructors() \n";
}

~CDestructors()
{
cout << "Called ~CDestructors() \n";
}

// Using `default` keyword
// ~CDestructors() = default;

// Using `delete` // I forbid this destructor
// ~CDestructors() = delete;
};

void destructers()
{
cout << "\n--- Basic Destructer Examples ---\n";
{
CDestructors obj;
}
}
}

// *2. Virtual Destructor
namespace Virtual
{
class CDestructorsBase // final => cannot inherit
{
public:
CDestructorsBase()
{
cout << "Called CDestructorsBase() \n";
}

virtual ~CDestructorsBase()
{
cout << "Called ~CDestructorsBase() \n";
}

// Using `default` keyword
// ~CDestructorsBase() = default;
};

class CDestructorsDerived : public CDestructorsBase
{
public:
CDestructorsDerived()
{
cout << "Called CDestructorsDerived() \n";
}

~CDestructorsDerived() override
{
cout << "Called ~CDestructorsDerived() \n";
}
};

void destructers()
{
cout << "\n--- Virtual Destructer Examples ---\n";
CDestructorsDerived *derived = {new CDestructorsDerived()};
CDestructorsBase *base{derived};
delete base;
// without virtual -> only call ~CDestructorsBase()
// with virtual -> call ~CDestructorsBase() && ~CDestructorsDerived()
}
}

struct CDestructorsAutoRuner
{
CDestructorsAutoRuner()
{
Basic::destructers();
Virtual::destructers();
}
};

static CDestructorsAutoRuner instance;
Loading