{"id":50338739,"url":"https://github.com/tigran-sargsyan-w/cpp-module-03","last_synced_at":"2026-05-29T15:30:25.375Z","repository":{"id":329173966,"uuid":"1118367215","full_name":"tigran-sargsyan-w/cpp-module-03","owner":"tigran-sargsyan-w","description":"This module is designed to help you understand inheritance in C++.","archived":false,"fork":false,"pushed_at":"2025-12-23T20:49:33.000Z","size":47,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T11:49:04.027Z","etag":null,"topics":["42","42-school","claptrap","class-design","constructors","cpp","cpp98","destructors","diamond-problem","diamondtrap","fragtrap","inheritance","multiple-inheritance","oop","orthodox-canonical-class","polymorphism","scavtrap"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tigran-sargsyan-w.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-17T16:41:27.000Z","updated_at":"2025-12-23T20:50:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tigran-sargsyan-w/cpp-module-03","commit_stats":null,"previous_names":["tigran-sargsyan-w/cpp-module-03"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tigran-sargsyan-w/cpp-module-03","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fcpp-module-03","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fcpp-module-03/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fcpp-module-03/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fcpp-module-03/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tigran-sargsyan-w","download_url":"https://codeload.github.com/tigran-sargsyan-w/cpp-module-03/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigran-sargsyan-w%2Fcpp-module-03/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33659872,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["42","42-school","claptrap","class-design","constructors","cpp","cpp98","destructors","diamond-problem","diamondtrap","fragtrap","inheritance","multiple-inheritance","oop","orthodox-canonical-class","polymorphism","scavtrap"],"created_at":"2026-05-29T15:30:22.780Z","updated_at":"2026-05-29T15:30:25.353Z","avatar_url":"https://github.com/tigran-sargsyan-w.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# C++ Module 03 – Inheritance \u0026 Diamond Problem 🧬💎\n\n✅ **Status**: Completed – all exercises  \n🏫 **School**: 42 – C++ Modules (Module 03)  \n🏅 **Score**: 100/100\n\n\u003e *Single inheritance, multiple inheritance, method overriding, base/derived behavior, and the classic “diamond” problem.*\n\n---\n\n## 📚 Table of Contents\n\n* [Description](#-description)\n* [Goals of the Module](#-goals-of-the-module)\n* [Exercises Overview](#-exercises-overview)\n\n  * [ex00 – ClapTrap](#ex00--claptrap)\n  * [ex01 – ScavTrap](#ex01--scavtrap)\n  * [ex02 – FragTrap](#ex02--fragtrap)\n  * [ex03 – DiamondTrap](#ex03--diamondtrap)\n* [Requirements](#-requirements)\n* [Build \u0026 Run](#-build--run)\n* [Repository Layout](#-repository-layout)\n* [Testing Tips](#-testing-tips)\n* [Quick Cheat Sheets](#-quick-cheat-sheets)\n\n  * [C++ Inheritance Modes](#c-inheritance-modes--quick-cheat-sheet)\n  * [C++ OOP Keywords](#c-oop-keywords-inheritance--polymorphism--quick-cheat-sheet)\n* [42 Notes](#-42-notes)\n\n---\n\n## 📝 Description\n\nThis repository contains my solutions to **42’s C++ Module 03 (C++98)**.\n\nThe module focuses on **inheritance** and how base/derived classes interact:\n\n* Single inheritance (`ClapTrap` → `ScavTrap` / `FragTrap`)\n* Overriding behavior (e.g., redefining `attack()` in derived classes)\n* Understanding constructor/destructor order\n* Multiple inheritance and the **diamond problem** (`DiamondTrap`)\n* Sharing a single base with **virtual inheritance**\n\nAll exercises are written in **C++98** and compiled with strict flags (`-Wall -Wextra -Werror -std=c++98`).\n\n---\n\n## 🎯 Goals of the Module\n\nConcepts practiced in this module:\n\n* **Inheritance** (`public` inheritance for “is-a”)\n* **Overriding** methods and calling base implementations when needed\n* **Constructor initialization lists** in an inheritance chain\n* **Rule of Three** (copy constructor, assignment operator, destructor)\n* **Multiple inheritance** and resolving ambiguity\n* **Virtual inheritance** to solve the “diamond” (single shared base)\n\n---\n\n## 📦 Exercises Overview\n\n### ex00 – ClapTrap\n\n\u003e A small combat-style class used as a base for the rest of the module.\n\n**Goal:**\nImplement `ClapTrap` with the canonical behavior:\n\n* `attack(target)` consumes energy and prints an action\n* `takeDamage(amount)` decreases hit points\n* `beRepaired(amount)` consumes energy and restores hit points\n\n**Concepts practiced:**\n\n* Basic class design\n* State management (HP/EP/AD)\n* Copy / assignment / destructor (Rule of Three)\n\n---\n\n### ex01 – ScavTrap\n\n\u003e First derived class: specialized behavior + custom stats.\n\n**Goal:**\nCreate `ScavTrap` inheriting from `ClapTrap`, with:\n\n* Updated default stats (HP/EP/AD according to the subject)\n* Overridden `attack()` (ScavTrap-style message)\n* New ability: `guardGate()`\n\n**Concepts practiced:**\n\n* `public` inheritance and overriding\n* Derived class constructors calling base constructors\n\n---\n\n### ex02 – FragTrap\n\n\u003e Second derived class: high energy, friendly vibes.\n\n**Goal:**\nCreate `FragTrap` inheriting from `ClapTrap`, with:\n\n* Updated default stats (HP/EP/AD)\n* New ability: `highFivesGuys()`\n\n**Concepts practiced:**\n\n* More inheritance practice\n* Consistent canonical form across classes\n\n---\n\n### ex03 – DiamondTrap\n\n\u003e Multiple inheritance + the “diamond” problem.\n\n**Goal:**\nCreate `DiamondTrap` inheriting from both `FragTrap` and `ScavTrap`, while:\n\n* Keeping **one** shared `ClapTrap` base (via **virtual inheritance**)\n* Having its own `name` (DiamondTrap identity)\n* Storing the base name as `DiamondTrapName_clap_name`\n* Using `ScavTrap::attack()`\n* Adding `whoAmI()` to print both names:\n\n  * DiamondTrap’s own name\n  * ClapTrap’s name\n\n**Concepts practiced:**\n\n* Multiple inheritance\n* Ambiguity resolution (`Base::method()`)\n* `virtual public Base` to ensure a single shared base\n\n---\n\n## 🛠 Requirements\n\nFrom the subject (typical for 42 C++ modules):\n\n* **Compiler**: `c++`\n* **Flags**:\n\n  * `-Wall -Wextra -Werror`\n  * `-std=c++98`\n* **OS**: any Unix-like system (Linux / macOS)\n* **No external libraries** (no C++11+)\n\n---\n\n## ▶️ Build \u0026 Run\n\nClone the repository and build each exercise separately.\n\n```bash\ngit clone \u003cthis-repo-url\u003e\ncd cpp-module-03\n```\n\n### ex00 – ClapTrap\n\n```bash\ncd ex00\nmake\n./claptrap\n```\n\n### ex01 – ScavTrap\n\n```bash\ncd ex01\nmake\n./scavtrap\n```\n\n### ex02 – FragTrap\n\n```bash\ncd ex02\nmake\n./fragtrap\n```\n\n### ex03 – DiamondTrap\n\n```bash\ncd ex03\nmake\n./diamondtrap\n```\n\n\u003e Executable names may differ depending on your Makefiles / implementation.\n\n---\n\n## 📂 Repository Layout\n\n```text\ncpp-module-03/\n├── ex00/\n│   ├── Makefile\n│   ├── ClapTrap.hpp\n│   ├── ClapTrap.cpp\n│   └── main.cpp\n│\n├── ex01/\n│   ├── Makefile\n│   ├── ClapTrap.hpp / ClapTrap.cpp\n│   ├── ScavTrap.hpp / ScavTrap.cpp\n│   └── main.cpp\n│\n├── ex02/\n│   ├── Makefile\n│   ├── ClapTrap.hpp / ClapTrap.cpp\n│   ├── FragTrap.hpp / FragTrap.cpp\n│   └── main.cpp\n│\n└── ex03/\n    ├── Makefile\n    ├── ClapTrap.hpp / ClapTrap.cpp\n    ├── ScavTrap.hpp / ScavTrap.cpp\n    ├── FragTrap.hpp / FragTrap.cpp\n    ├── DiamondTrap.hpp / DiamondTrap.cpp\n    └── main.cpp\n```\n\n---\n\n## 🔍 Testing Tips\n\n### General\n\n* Check that **HP/EP/AD** values match the subject defaults in each class.\n* Verify that **energy can run out** and actions stop when EP = 0.\n* Verify that **dead traps** (HP = 0) cannot attack/repair.\n\n### ex03 (DiamondTrap)\n\n* Confirm `ClapTrap` constructor is called **once** (shared base).\n* Confirm `DiamondTrap::attack()` uses **ScavTrap-style** output.\n* Confirm `whoAmI()` prints:\n\n  * `DiamondTrap name: Ruby`\n  * `ClapTrap name: Ruby_clap_name`\n* Confirm destructor order is reasonable (derived → bases, virtual base last).\n\n---\n\n## 🧠 Quick Cheat Sheets\n\n## C++ Inheritance Modes — Quick Cheat Sheet\n\n**Mental model:**\n\n* `Human` = base class\n* `Warrior` = derived class\n\n---\n\n### 1) `public` — **“Warrior IS a Human”** ✅\n\n```cpp\nclass Warrior : public Human {};\n```\n\n#### ✅ What works (outside code)\n\n```cpp\nvoid greet(Human\u0026 h);\n\nWarrior w;\ngreet(w);        // ✅ OK (is-a)\nHuman* p = \u0026w;   // ✅ OK\nHuman\u0026 r = w;    // ✅ OK\n```\n\n#### 🧠 When to use\n\n* Classic OOP **is-a** relationship\n* Typical for school exercises (`ScavTrap` is-a `ClapTrap`)\n\n---\n\n### 2) `protected` — **“Outside: NOT Human, but for subclasses: yes”**\n\n```cpp\nclass Warrior : protected Human {};\n```\n\n#### ❌ Forbidden (outside code)\n\n```cpp\nvoid greet(Human\u0026 h);\n\nWarrior w;\ngreet(w);        // ❌ ERROR (outside can’t treat Warrior as Human)\nHuman* p = \u0026w;   // ❌ ERROR\nHuman\u0026 r = w;    // ❌ ERROR\n```\n\n#### ✅ What you *can* do\n\n#### 1) Use `Warrior` as its own type\n\n```cpp\nvoid train(Warrior\u0026 w);\n\nWarrior w;\ntrain(w);        // ✅ OK\n```\n\n#### 2) Inside `Warrior` you can access base members\n\n```cpp\nclass Warrior : protected Human\n{\npublic:\n    void demo()\n    {\n        attack();        // ✅ if attack() was public/protected in Human\n        hitPoints = 10;  // ✅ if hitPoints was protected in Human\n    }\n};\n```\n\n#### 3) Inside a subclass of `Warrior` you can still access base members\n\n```cpp\nclass EliteWarrior : public Warrior\n{\npublic:\n    void demo()\n    {\n        attack();        // ✅ base is visible as protected\n        hitPoints = 99;  // ✅ if it was protected in Human\n    }\n};\n```\n\n### 🧠 When to use\n\n* Rare\n* You want to **hide “is-a” from outside**, but but keep the base accessible for subclasses.\n\n---\n\n### 3) `private` — **“Warrior is NOT Human; it just uses Human internally”** 🔒\n\n```cpp\nclass Warrior : private Human {};\n// For `class`, this is the default:\nclass Warrior : Human {}; // ❗ private inheritance by default\n```\n\n#### ❌ Forbidden (outside code)\n\n```cpp\nvoid greet(Human\u0026 h);\n\nWarrior w;\ngreet(w);        // ❌ ERROR\nHuman* p = \u0026w;   // ❌ ERROR\nHuman\u0026 r = w;    // ❌ ERROR\n```\n\n#### ❌ Forbidden (even for subclasses of `Warrior`)\n\n```cpp\nclass EliteWarrior : public Warrior\n{\npublic:\n    void demo()\n    {\n        attack();        // ❌ ERROR (Human part became private inside Warrior)\n        hitPoints = 99;  // ❌ ERROR\n    }\n};\n```\n\n### ✅ What you *can* do\n\n#### 1) Inside `Warrior` you can use the base (implementation detail)\n\n```cpp\nclass Warrior : private Human\n{\npublic:\n    void demo()\n    {\n        attack();        // ✅ OK inside Warrior\n        hitPoints = 10;  // ✅ if protected in Human\n    }\n};\n```\n\n#### 2) Expose only what you want (wrapper / selective re-export)\n\n```cpp\nclass Warrior : private Human\n{\npublic:\n    using Human::attack; // ✅ make only this base method public\n\n    void specialMove();\n};\n```\n\nOr forward manually:\n\n```cpp\nclass Warrior : private Human\n{\npublic:\n    void attackPublic(const std::string\u0026 target)\n    {\n        attack(target);  // ✅ call base inside\n    }\n};\n```\n\n### 🧠 When to use\n\n* Rare (often composition is better)\n* When inheritance is **only for code reuse**, not for “is-a”\n\n---\n\n### Default rule (VERY IMPORTANT) ⚠️\n\n```cpp\nclass A : B {};   // = private inheritance (default)\nstruct A : B {};  // = public inheritance (default)\n```\n\n---\n\n### Ultra-short summary\n\n* `public`    → **IS-A**\n* `protected` → **IS-A only for subclasses**\n* `private`   → **implementation detail (code reuse), not IS-A**\n\n---\n\n## C++ OOP Keywords (Inheritance \u0026 Polymorphism) — Quick Cheat Sheet\n\n\u003e A compact list of keywords/idioms that matter most around inheritance.\n\n---\n\n### 1) `virtual` (methods) — **polymorphism** 🎭\n\nIf a base method is `virtual`, a call through `Base\u0026` / `Base*` will dispatch to the derived override.\n\n```cpp\nclass Base {\npublic:\n    virtual void speak();\n};\n\nclass Der : public Base {\npublic:\n    void speak() override;\n};\n```\n\n**Why:** “one interface — multiple implementations”.\n\n---\n\n### 2) `override` — **compile-time check that you really override** ✅\n\n```cpp\nvoid speak() override;\n```\n\nIf the signature doesn’t match exactly (params, `const`, refs, etc.), you get a compile error.\n\n---\n\n### 3) `final` — **prevent inheritance / prevent further overrides** 🧱\n\n#### Class can’t be inherited:\n\n```cpp\nclass Boss final {};\n```\n\n#### Method can’t be overridden further:\n\n```cpp\nclass Base {\npublic:\n    virtual void speak() final;\n};\n```\n\n---\n\n### 4) `virtual` destructor — **safe delete via base pointer** 🧨\n\nIf you have polymorphism (virtual methods) and you might do `delete basePtr;`, the base destructor should almost always be `virtual`.\n\n```cpp\nclass Base {\npublic:\n    virtual ~Base();\n};\n\nclass Der : public Base {\npublic:\n    ~Der();\n};\n\nBase* p = new Der();\ndelete p; // ✅ calls ~Der(), then ~Base()\n```\n\nWithout `virtual ~Base()` you risk only `~Base()` being called.\n\n---\n\n### 5) `protected` — **visible to derived classes, hidden from outside** 🛡️\n\n```cpp\nclass Base {\nprotected:\n    int hp;\n};\n```\n\n**Idea:** derived classes can access it; external code cannot.\n\n---\n\n### 6) `using Base::method;` — **keep overloads visible / selectively re-export** 🔎\n\nA derived method with the same name can hide base overloads (name hiding).\n\n```cpp\nclass Base {\npublic:\n    void attack(int);\n    void attack(double);\n};\n\nclass Der : public Base {\npublic:\n    using Base::attack; // ✅ bring base overloads back into scope\n\n    void attack(const char*);\n};\n```\n\nAlso handy with `private` inheritance: you can expose only specific base methods.\n\n---\n\n### 7) `explicit` (constructors) — **block implicit conversions** 🚫\n\n```cpp\nclass Money {\npublic:\n    explicit Money(int cents);\n};\n\nMoney m = 42;   // ❌ not allowed\nMoney m2(42);   // ✅ allowed\n```\n\n---\n\n### 8) `= delete` / `= default` — **control copy/assignment** 🧰\n\n```cpp\nclass Base {\npublic:\n    Base() = default;\n    Base(const Base\u0026) = delete;\n    Base\u0026 operator=(const Base\u0026) = delete;\n    virtual ~Base() = default;\n};\n```\n\n**Why:** some bases must not be copyable (resources, ownership, etc.).\n\n---\n\n### 9) `Base::method()` — **explicitly call the base version** 🎯\n\nUseful with overriding / multiple inheritance.\n\n```cpp\nvoid Der::attack(const std::string\u0026 target)\n{\n    Base::attack(target); // call base implementation\n}\n```\n\n---\n\n### Tiny reminder: `virtual` has 2 different meanings in C++ ⚠️\n\n* `virtual` **on methods** → polymorphism (`override` / `final`)\n* `virtual` **in inheritance** (`class A : virtual public B`) → a single shared base in the “diamond”\n\n---\n\n## 🧾 42 Notes\n\n* C++ modules at 42 generally target **C++98** (no modern features unless explicitly allowed).\n* There is no Norminette for C++, but clean structure and readable output logs help a lot during evaluation.\n* If your logs differ slightly, check:\n\n  * Constructor/destructor order\n  * Which class version of `attack()` is being called\n  * Whether your base is truly shared in the diamond (`virtual public ClapTrap`)\n\n---\n\nIf you’re a 42 student working on the same module: feel free to explore, get inspired, but **write your own implementation** — that’s where the learning happens. 🚀\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftigran-sargsyan-w%2Fcpp-module-03","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftigran-sargsyan-w%2Fcpp-module-03","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftigran-sargsyan-w%2Fcpp-module-03/lists"}