From 5dc061c3fc3c47dc635f6bc33adb055d4778895e Mon Sep 17 00:00:00 2001 From: Phong Nguyen Date: Mon, 2 Mar 2026 09:32:46 +0700 Subject: [PATCH 1/2] Update cembedded doc --- src/cembedded/README.md | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/cembedded/README.md b/src/cembedded/README.md index e081882..b0de8e5 100644 --- a/src/cembedded/README.md +++ b/src/cembedded/README.md @@ -1,16 +1,13 @@ # 1. Core C Basics for Embedded Systems -``` -Your Foundation for Embedded Programming -``` **Topics Covered:** -- Variables & Data Types -- Operators & Control Flow -- Functions -- Arrays & Strings -- Basic Input/Output -- Practice Problems +- 1.1 Variables & Data Types +- 1.2 Operators & Control Flow +- 1.3 Functions +- 1.4 Arrays & Strings +- 1.5 Basic Input/Output +- 1.6 Practice Problems ## 1.1 Variables & Data Types @@ -268,10 +265,12 @@ printf("Hello %s, you are %d years old!\n", name, age); **Common Format Specifiers** -| Specifier | Data Type | Example | +| Specifier | Data Type | Example | |---------------|----------------|------------------------------| | %d or %i | int | printf("%d", 42); | +| %ld | long | printf("%lu", 255); | | %u | unsigned int | printf("%u", 255); | +| %lu | uint32_t | printf("%lu", 255); | | %f | float/double | printf("%.2f", 3.14); | | %c | char | printf("%c", 'A'); | | %s | string | printf("%s", "Hello"); | @@ -281,9 +280,6 @@ printf("Hello %s, you are %d years old!\n", name, age); ## 1.6. Practice Problems -Here are some hands-on exercises to solidify your understanding. Try to solve these -without looking at solutions first! - **Problem 1: Temperature Converter** Write a program that converts temperature from Celsius to Fahrenheit using the From eac3d2bfbeeda4b336cd3aebe6935e6c4c8636e4 Mon Sep 17 00:00:00 2001 From: Phong Nguyen Date: Mon, 2 Mar 2026 11:24:14 +0700 Subject: [PATCH 2/2] Add the class relationship examples --- CMakeLists.txt | 1 + src/core/datatypes/class/README.md | 251 +++++++++++++++++++++- src/core/datatypes/class/Relationship.cpp | 157 ++++++++++++++ 3 files changed, 408 insertions(+), 1 deletion(-) create mode 100644 src/core/datatypes/class/Relationship.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e32591..a7e11f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,6 +122,7 @@ set(APP_SOURCES "src/patterns/creational/AbstractFactory.cpp" "src/patterns/creational/Builder.cpp" "src/patterns/creational/Prototype.cpp" + "src/core/datatypes/class/Relationship.cpp" ## Exceptions "src/core/exception/BasicHandle.cpp" "src/core/exception/ThrowNoexcept.cpp" diff --git a/src/core/datatypes/class/README.md b/src/core/datatypes/class/README.md index 6e7c99b..289a91e 100644 --- a/src/core/datatypes/class/README.md +++ b/src/core/datatypes/class/README.md @@ -15,4 +15,253 @@ operator OP (type_of_X, type_of_Y) - It give access to only once specific function. ### 1.3. Class - Friend Class : I trust this class to see my private data -- It give access to all member functions of another class. \ No newline at end of file +- It give access to all member functions of another class. + +## 2. Class Relationship +### 2.1. Composition +- **Part-of, strong ownership** +- The member is part of the class +- The member can only belong to one class at a time +- The member has its existence managed by the class +- The member does not know about the existence of the class + +- UML: +```cpp ++------------------------+ +| Car | ++------------------------+ +| - engine : Engine | ++------------------------+ + ♦ + │ + │ ++------------------------+ +| Engine | ++------------------------+ +| + Engine() | +| + ~Engine() | ++------------------------+ + +class Engine +{ +public: + Engine() { std::cout << "Engine created\n"; } + ~Engine() { std::cout << "Engine destroyed\n"; } +}; + +class Car +{ +private: + Engine engine; // composition + +public: + Car() { std::cout << "Car created\n"; } + ~Car() { std::cout << "Car destroyed\n"; } +}; +``` + +## 2.2. Aggregations +- **Has-a, weak ownership** +- The member is part of the class +- The member can belong to more than one class at a time +- The member does not have its existence managed by the class +- The member does not know about the existence of the class + +- UML: +```cpp ++-----------------------------+ +| Department | ++-----------------------------+ +| - teacher : Teacher* | ++-----------------------------+ + ◇ + │ + │ ++-----------------------------+ +| Teacher | ++-----------------------------+ +| - name : std::string | ++-----------------------------+ + +class Teacher +{ +public: + std::string name; + Teacher(const std::string& n) : name(n) {} +}; + +class Department +{ +private: + Teacher* teacher; // aggregation + +public: + Department(Teacher* t) : teacher(t) {} +}; +``` + +## 2.3. Associations +- **Uses-a, loose relationship** +- The associated member is otherwise unrelated to the class +- The associated member can belong to more than one class at a time +- The associated member does not have its existence managed by the class +- The associated member may or may not know about the existence of the class +- UML +```cpp ++---------------------+ +---------------------+ +| Doctor |-----------------| Patient | ++---------------------+ +---------------------+ +| + treat(p:Patient&) | | - name : string | ++---------------------+ +---------------------+ + +class Patient +{ +public: + std::string name; +}; + +class Doctor +{ +public: + void treat(Patient& p) + { + std::cout << "Treating " << p.name << "\n"; + } +}; +``` + +## 2.4. Dependency +- **Denpends-on** +- One class uses another class to perform a task. +- It is temporarily created, used, and then destroyed, or passed into a member function from an external source. +- UML +```cpp ++---------------------+ +| Car | ++---------------------+ +| + start() | ++---------------------+ + - - - - - - - - - - - - - - - - - - > + +---------------------+ + | Logger | + +---------------------+ + | + log(msg:string) | + +---------------------+ +class Logger +{ +public: + void log(const std::string& msg) + { + std::cout << msg << std::endl; + } +}; + +class Car +{ +public: + void start() + { + Logger logger; // dependency + logger.log("Car started"); + } +}; + +``` +## 2.5. Container +- The class one class provides a container to hold multiple objects of another type +- UML +```cpp +#include + ++-----------------------------+ +| Library1 | ++-----------------------------+ +| - books : vector | ++-----------------------------+ + ♦ + │ + │ ++-----------------------------+ +| string | ++-----------------------------+ +class Library1 +{ +private: + std::vector books; // copy values +}; + ++-----------------------------+ +| Library2 | ++-----------------------------+ +| - teachers : vector | ++-----------------------------+ + ◇ + │ + │ ++-----------------------------+ +| Teacher | ++-----------------------------+ +class Library2 +{ +private: + std::vector teachers; // store pointers +}; + +``` + +## 2.6. Inheritance +- **Is-a** +```cpp ++----------------------+ +| Animal | ++----------------------+ +| + eat() | ++----------------------+ + △ + │ + │ ++----------------------+ +| Dog | ++----------------------+ +| + bark() | ++----------------------+ +class Animal +{ +public: + void eat() { std::cout << "Eating\n"; } +}; + +class Dog : public Animal +{ +public: + void bark() { std::cout << "Woof\n"; } +}; +``` + +## 2.7 Embedded a.k.a Nested/Inner Class +- Type-level containment +```cpp ++----------------------+ +| Car | ++----------------------+ +| | ++----------------------+ + (+) + │ + │ ++----------------------+ +| Engine | ++----------------------+ +| + start() | ++----------------------+ + +class Car +{ +public: + class Engine + { + public: + void start(); + }; +}; +``` \ No newline at end of file diff --git a/src/core/datatypes/class/Relationship.cpp b/src/core/datatypes/class/Relationship.cpp new file mode 100644 index 0000000..ed50a60 --- /dev/null +++ b/src/core/datatypes/class/Relationship.cpp @@ -0,0 +1,157 @@ +// cppcheck-suppress-file [functionStatic] +#include +#include "ExampleRegistry.h" + +namespace { + +namespace Composition { +// Engine is a part of the Car +// Engine is managed by the Car +class Engine { + public: + Engine() { std::cout << "Engine created\n"; } + ~Engine() { std::cout << "Engine destroyed\n"; } +}; + +class Car { + public: + Car() { std::cout << "Car created\n"; } + ~Car() { std::cout << "Car destroyed\n"; } + + private: + Engine engine; // composition +}; + +void run() { + std::cout << "\n---Composition---\n"; + Car car; +} +}; // namespace Composition + +namespace Aggregations { +// Teacher is a part of the Department +// Teacher can belong to one or more Department +// Department does not managed Patient existence +class Teacher { + public: + std::string name; + explicit Teacher(const std::string& n) : name(n) { + std::cout << "Teacher created: " << name << "\n"; + } + + ~Teacher() { std::cout << "Teacher destroyed: " << name << "\n"; } +}; + +class Department { + private: + Teacher* teacher; // aggregation + + public: + explicit Department(Teacher* t) : teacher(t) { + std::cout << "Department created \n"; + } + + ~Department() { std::cout << "Department destroyed \n"; } +}; + +void run() { + std::cout << "\n---Aggregations---\n"; + Teacher t{"Mr.A"}; + { + Department dep1{&t}; + Department dep2{&t}; + } +} +}; // namespace Aggregations + +// Doctor uses Patient +// Doctor does not managed Patient existence +namespace Associations { +class Patient { + public: + Patient() { std::cout << "Patient created \n"; } + ~Patient() { std::cout << "Patient destroyed \n"; } + std::string name; +}; + +class Doctor { + public: + Doctor() { std::cout << "Doctor created \n"; } + ~Doctor() { std::cout << "Doctor destroyed \n"; } + void treat(const Patient& p) { std::cout << "Treating " << p.name << "\n"; } +}; + +void run() { + std::cout << "\n---Associations---\n"; + Patient p{}; + Doctor d{}; + d.treat(p); +} +} // namespace Associations + +// Car creates and uses Logger to log +namespace Dependency { +class Logger { + public: + Logger() { std::cout << "Logger created \n"; } + ~Logger() { std::cout << "Logger destroyed \n"; } + + void log(const std::string& msg) { std::cout << msg << std::endl; } +}; + +class Car { + public: + Car() { std::cout << "Car created \n"; } + ~Car() { std::cout << "Car destroyed \n"; } + + void start() { + std::cout << "Car started\n"; + Logger logger; // dependency + logger.log("Log Car started"); + } +}; +void run() { + std::cout << "\n---Dependency---\n"; + Car car{}; + car.start(); +} +} // namespace Dependency + +namespace Container { +// class Library1 { +// private: +// std::vector books; // copy values +// }; + +// class Library2 { +// private: +// std::vector teachers; // store pointers +// }; +} // namespace Container + +namespace InnerClass { +class Car { + public: + class Engine { + public: + void start(); + }; +}; +} // namespace InnerClass +} // namespace + +class Relationship : public IExample { + std::string group() const override { return "core/class"; }; + + std::string name() const override { return "Relationship"; }; + std::string description() const override { return "Relationship examples"; }; + + void execute() override { + Composition::run(); + Aggregations::run(); + Associations::run(); + Dependency::run(); + }; +}; + +REGISTER_EXAMPLE(Relationship, "core/class", "Relationship"); \ No newline at end of file