cpp

exercises

exercises.cpp⚙️
/**
 * Object Relationships - Exercises
 * Compile: g++ -std=c++17 -Wall exercises.cpp -o exercises
 */

#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;

// ============================================================
// Exercise 1: Composition ⭐
// ============================================================

// TODO: Create Heart and Brain classes
// TODO: Create Human that composes Heart and Brain
// Heart and Brain should be destroyed with Human

void exercise1() {
    // Human h("Alice");
    // h.think();  // Brain::process()
    // h.pump();   // Heart::beat()
    cout << "(Implement Human with Heart and Brain composition)" << endl;
}

// ============================================================
// Exercise 2: Aggregation ⭐⭐
// ============================================================

// TODO: Create Book and Library
// Library aggregates Books (doesn't own them)
// Same book can be in multiple libraries

class Book {
    string title;
public:
    Book(const string& t) : title(t) {}
    string getTitle() const { return title; }
};

// TODO: Implement Library with vector<Book*>

void exercise2() {
    Book b1("C++ Primer"), b2("Design Patterns");
    // Library lib1("Main"), lib2("Branch");
    // lib1.addBook(&b1); lib1.addBook(&b2);
    // lib2.addBook(&b1);  // Same book in both
    cout << "(Implement Library aggregation)" << endl;
}

// ============================================================
// Exercise 3: Association ⭐⭐
// ============================================================

// TODO: Create Doctor and Patient with bidirectional association
// Doctor knows their patients
// Patient knows their doctors

void exercise3() {
    // Doctor doc("Dr. Smith");
    // Patient p1("Alice"), p2("Bob");
    // doc.addPatient(&p1);
    // doc.addPatient(&p2);
    // p1.addDoctor(&doc);
    cout << "(Implement Doctor-Patient association)" << endl;
}

// ============================================================
// Exercise 4: Dependency ⭐
// ============================================================

class Message {
    string text;
public:
    Message(const string& t) : text(t) {}
    string getText() const { return text; }
};

// TODO: Create Encryptor that encrypts a Message (dependency)
// TODO: Create Logger that logs a Message (dependency)

void exercise4() {
    Message msg("Hello World");
    // Encryptor enc;
    // cout << enc.encrypt(msg) << endl;  // Uses Message temporarily
    cout << "(Implement dependency relationship)" << endl;
}

// ============================================================
// Exercise 5: Smart Pointer Composition ⭐⭐
// ============================================================

// TODO: Create Computer with unique_ptr to CPU, RAM, GPU
// All components created and destroyed with Computer

void exercise5() {
    // Computer pc;
    // pc.run();  // Uses all components
    cout << "(Implement Computer with smart pointers)" << endl;
}

// ============================================================
// Exercise 6: Composition vs Inheritance ⭐⭐⭐
// ============================================================

// TODO: Refactor this inheritance to composition

class BadLogger {
public:
    void log(const string& msg) { cout << msg << endl; }
};

// Bad: Using inheritance for code reuse
class BadService : public BadLogger {
public:
    void doWork() {
        log("Working...");  // Inherited
    }
};

// TODO: Create GoodService using composition instead

void exercise6() {
    // GoodService service;
    // service.doWork();
    cout << "(Refactor to composition)" << endl;
}

// ============================================================
// Exercise 7: Full System ⭐⭐⭐
// ============================================================

// Design a simple school system:
// - School COMPOSES Departments (owns them)
// - Department AGGREGATES Teachers (doesn't own)
// - Teacher ASSOCIATES with Students (bidirectional)
// - Teacher uses Classroom (dependency)

void exercise7() {
    // School school("Tech High");
    // school.addDepartment("Math");
    // school.addDepartment("Science");
    // ... demonstrate all relationships
    cout << "(Design school system with all relationship types)" << endl;
}

// ============================================================
// MAIN
// ============================================================

int main() {
    cout << "=== Object Relationships Exercises ===" << endl;
    
    cout << "\nEx1: Composition" << endl;
    exercise1();
    
    cout << "\nEx2: Aggregation" << endl;
    exercise2();
    
    cout << "\nEx3: Association" << endl;
    exercise3();
    
    cout << "\nEx4: Dependency" << endl;
    exercise4();
    
    cout << "\nEx5: Smart Pointers" << endl;
    exercise5();
    
    cout << "\nEx6: Composition vs Inheritance" << endl;
    exercise6();
    
    cout << "\nEx7: Full System" << endl;
    exercise7();
    
    return 0;
}

// ============================================================
// ANSWERS
// ============================================================
/*
Ex1:
class Heart { public: void beat() { cout << "Beating" << endl; } };
class Brain { public: void process() { cout << "Thinking" << endl; } };
class Human {
    Heart heart; Brain brain; string name;
public:
    Human(const string& n) : name(n) {}
    void pump() { heart.beat(); }
    void think() { brain.process(); }
};

Ex2:
class Library {
    string name;
    vector<Book*> books;
public:
    Library(const string& n) : name(n) {}
    void addBook(Book* b) { books.push_back(b); }
};

Ex5:
class CPU { public: void compute() { cout << "Computing" << endl; } };
class RAM { public: void store() { cout << "Storing" << endl; } };
class GPU { public: void render() { cout << "Rendering" << endl; } };
class Computer {
    unique_ptr<CPU> cpu = make_unique<CPU>();
    unique_ptr<RAM> ram = make_unique<RAM>();
    unique_ptr<GPU> gpu = make_unique<GPU>();
public:
    void run() { cpu->compute(); ram->store(); gpu->render(); }
};

Ex6:
class Logger { public: void log(const string& m) { cout << m << endl; } };
class GoodService {
    Logger logger;  // Composition instead of inheritance
public:
    void doWork() { logger.log("Working..."); }
};
*/
Exercises - C++ Tutorial | DeepML