From 49c796095fbc5286e7efc947f662278aa51c2eba Mon Sep 17 00:00:00 2001 From: chuangtsh Date: Sun, 28 Dec 2025 16:23:18 +0800 Subject: [PATCH 1/2] finish draft for teaching materials --- cpp_oop/Makefile | 38 +++++++++++++ cpp_oop/README.md | 110 +++++++++++++++++++++++++++++++++++++ cpp_oop/include/Airplane.h | 23 ++++++++ cpp_oop/include/Car.h | 24 ++++++++ cpp_oop/include/Vehicle.h | 60 ++++++++++++++++++++ cpp_oop/src/Airplane.cpp | 23 ++++++++ cpp_oop/src/Car.cpp | 24 ++++++++ cpp_oop/src/Vehicle.cpp | 65 ++++++++++++++++++++++ cpp_oop/src/main.cpp | 54 ++++++++++++++++++ 9 files changed, 421 insertions(+) create mode 100644 cpp_oop/Makefile create mode 100644 cpp_oop/README.md create mode 100644 cpp_oop/include/Airplane.h create mode 100644 cpp_oop/include/Car.h create mode 100644 cpp_oop/include/Vehicle.h create mode 100644 cpp_oop/src/Airplane.cpp create mode 100644 cpp_oop/src/Car.cpp create mode 100644 cpp_oop/src/Vehicle.cpp create mode 100644 cpp_oop/src/main.cpp diff --git a/cpp_oop/Makefile b/cpp_oop/Makefile new file mode 100644 index 0000000..fe0fdda --- /dev/null +++ b/cpp_oop/Makefile @@ -0,0 +1,38 @@ +# Makefile for C++ OOP Tutorial +# Demonstrates header files, source files, enum, and extern + +CXX = g++ +CXXFLAGS = -Wall -Wextra -std=c++14 -I./include +TARGET = vehicle_demo + +# Source files +SRCS = src/Vehicle.cpp src/Car.cpp src/Airplane.cpp src/main.cpp + +# Object files +OBJS = $(SRCS:.cpp=.o) + +# Default target +all: $(TARGET) + +# Link object files to create executable +$(TARGET): $(OBJS) + $(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS) + @echo "Build complete! Run with: ./$(TARGET)" + +# Compile source files to object files +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c $< -o $@ + +# Run the program +run: $(TARGET) + ./$(TARGET) + +# Clean build files +clean: + rm -f $(OBJS) $(TARGET) + @echo "Clean complete!" + +# Rebuild everything +rebuild: clean all + +.PHONY: all run clean rebuild diff --git a/cpp_oop/README.md b/cpp_oop/README.md new file mode 100644 index 0000000..7516351 --- /dev/null +++ b/cpp_oop/README.md @@ -0,0 +1,110 @@ +# C++ OOP Tutorial + +2025 Winter Turtorial Supplementary C++, OOP的範例程式 + +## Topics Covered + +### 1. OOP (Object-Oriented Programming) +- **Encapsulation**: Private members in `Car` and `Airplane` classes +- **Inheritance**: `Car` and `Airplane` inherit from `Vehicle` +- **Polymorphism**: Virtual function `move()` with different implementations + +### 2. Header File (.h) & Source File (.cpp) + +#### Header File (`.h`) +- 放 declarations(宣告)、include、extern +- 別人看 header file 就可以知道有什麼功能 +- 統一放在資料夾`include` + +例如: `Vehicle.h`, `Car.h`, `Airplane.h` + +#### Source File (`.cpp`) +- 實際地把 header file 中的東西 implement 出來 +- 放在資料夾`src` +- `main.cpp`是主程式,因為只有`main()`所以我沒寫`main.h` + +例如: `Vehicle.cpp`, `Car.cpp`, `Airplane.cpp` + + +### 3. enum (Enumeration) + +enum 是一個 user-defined type,代表一組有限的命名整數。 + + +**用途:** +- 劃分不同的類別或狀態 +- 讓程式碼更容易閱讀和維護 +- 範例 1: Color +- 範例 2: VehicleStatus +- 都在`Vehicle.h` + + +### 4. Global Variable & extern + +**重要規則:** +- extern 只要宣告一次 +- 接下來都用 include header file 的方式 +- **初始化只要一次**(多個程式嘗試初始化會造成問題!) + +**本專案範例:** +- `Vehicle.h`: 宣告 `extern int global_vehicle_count;` +- `Vehicle.cpp`: 初始化 `int global_vehicle_count = 0;` +- `main.cpp`: 透過 include `Car.h` (which includes `Vehicle.h`) 使用這個變數 + +## Project Structure + +``` +cpp_oop/ +├── include/ +│ ├── Vehicle.h # base class + enum + extern 宣告(declaration) +│ ├── Car.h # Car class declaration +│ └── Airplane.h # Airplane declaration +├── src/ +│ ├── Vehicle.cpp # Vehicle 實作(implementation) + global 變數初始化 +│ ├── Car.cpp # Car implementation +│ ├── Airplane.cpp # Airplane implementation +│ └── main.cpp # 主程式 +├── Makefile # 編譯腳本 +└── README.md # 本檔案 +``` + +## How to Build and Run + +- 由於有多個檔案需要編譯,我叫AI寫了`Makefile` +- `Makefile`可以包含編譯的指令,給`make`工具使用 +- 學ROS時會有`CMakeLists.txt`,功能比Makefile更多,編譯過程中會自動生成`Makefile` +- 不需要打開`Makefile` +- 想要自己用`g++`之類的編譯請問AI + +### Entering the directory in docker container +```bash +# 以免有人本地端無法編譯C++,這邊的指令是在container裡編譯 +# 編譯管道與ROS無關,只是單純的 make工具 與 g++ compiler + +### Build docker environement(Same as the homepage READE.md) +- `cd docker` +- docker compose up -d +- *Container ros2_tutorial Running* # expected o/p, dont type +- docker exec -it ros2_tutorial bash + +### Enter cpp_oop directory +cd cpp_oop +``` + +### Using Makefile +```bash +# type the command in terminal + +# Build the project +make + +# Build and run +make run + +# Clean build files +make clean + +# Rebuild from scratch +make rebuild +``` + diff --git a/cpp_oop/include/Airplane.h b/cpp_oop/include/Airplane.h new file mode 100644 index 0000000..ff1326f --- /dev/null +++ b/cpp_oop/include/Airplane.h @@ -0,0 +1,23 @@ +// to avoid multiple include (include guard) +#ifndef AIRPLANE_H +#define AIRPLANE_H + +#include "Vehicle.h" + +// Airplane is-a Vehicle, so Airplane inherits from Vehicle just like Car +class Airplane : public Vehicle { +private: + int altitude; + +public: + // Constructor of Airplane + Airplane(int fuel, int max_speed, int altitude, Color color = BLUE); + + // 除了inherited from Vehicle的public getter/setter function,Airplane還有自己的函式 + void climb(int meters); + int getAltitude() const; + + std::string move() const override; // declare with override to enable polymorphism +}; + +#endif diff --git a/cpp_oop/include/Car.h b/cpp_oop/include/Car.h new file mode 100644 index 0000000..5a200e0 --- /dev/null +++ b/cpp_oop/include/Car.h @@ -0,0 +1,24 @@ +// to avoid multiple include (include guard) +#ifndef CAR_H +#define CAR_H + +#include "Vehicle.h" // to use class declaration of Vehicle + + +// Car is-a Vehicle, so Car inherits from Vehicle +class Car : public Vehicle { +private: + int seat_count; // encapsulated + +public: + // Constructor with color parameter + Car(int fuel, int max_speed, int seat_count, Color color = RED); + + // 除了inherited from Vehicle的public getter/setter function,Car還有自己的函式 + void drive(); + int getSeatCount() const; + + std::string move() const override; // declare with override to enable polymorphism +}; + +#endif diff --git a/cpp_oop/include/Vehicle.h b/cpp_oop/include/Vehicle.h new file mode 100644 index 0000000..16c9ac3 --- /dev/null +++ b/cpp_oop/include/Vehicle.h @@ -0,0 +1,60 @@ +// to avoid multiple include (include guard) +#ifndef VEHICLE_H +#define VEHICLE_H + +#include + +// enum: a user-defined type that represents a finite set of named integer +enum Color { + RED, // 預設 RED==0 + GREEN, // GREEN==1 + BLUE, // BLUE==2 + YELLOW, + BLACK, + WHITE +}; + +// 用來表示交通工具的狀態 +enum VehicleStatus { + IDLE = 0, + MOVING = 1, + REFUELING = 2, + MAINTENANCE = 3 +}; + +// 在.h宣告變數extern但不初始化 +extern int global_vehicle_count; + +// 交通工具(抽象概念) +class Vehicle { +protected: + int fuel; // 燃料 + int max_speed; // 最大速度 + Color color; // 顏色 (使用 enum) + VehicleStatus status; // 狀態 (使用 enum) + +public: + Vehicle(int fuel, int max_speed, Color color = WHITE); + virtual ~Vehicle(); // destructor + + void refuel(int amount); + + // getter function (get the values of these variables but not directly accessing them) + int getFuel() const; // const -> this function should not modify the variable in the class + int getMaxSpeed() const; + Color getColor() const; + VehicleStatus getStatus() const; + + // setter function (set the values of specified varaible) + void setStatus(VehicleStatus new_status); + + // demo how to use enum for if-statement + std::string getColorName() const; + + // Polymorphism interface, declared virtual + // this is pure virtual function(so the child of Vehicle must declare own move function) + // pure virtual function does not need function definition here + virtual std::string move() const = 0; +}; + +#endif diff --git a/cpp_oop/src/Airplane.cpp b/cpp_oop/src/Airplane.cpp new file mode 100644 index 0000000..e738aa9 --- /dev/null +++ b/cpp_oop/src/Airplane.cpp @@ -0,0 +1,23 @@ +#include "Airplane.h" + +Airplane::Airplane(int fuel, int max_speed, int altitude, Color color) + : Vehicle(fuel, max_speed, color), altitude(altitude) {} + +void Airplane::climb(int meters) { + if (fuel > 0) { + status = MOVING; // 使用 enum 設定狀態 + altitude += meters; + fuel--; + } + else { + status = IDLE; + } +} + +int Airplane::getAltitude() const { + return altitude; +} + +std::string Airplane::move() const { + return "Airplane flies in the sky"; +} diff --git a/cpp_oop/src/Car.cpp b/cpp_oop/src/Car.cpp new file mode 100644 index 0000000..fb61fd5 --- /dev/null +++ b/cpp_oop/src/Car.cpp @@ -0,0 +1,24 @@ +#include "Car.h" +// no need to include Vehicle.h, since Car.h has included Vehicle.h + +Car::Car(int fuel, int max_speed, int seat_count, Color color) + : Vehicle(fuel, max_speed, color), seat_count(seat_count) {} + // Car's constructor must call the constructor of the parent(Vehicle) + +void Car::drive() { + if (fuel > 0) { + status = MOVING; // 使用 enum 設定狀態 + fuel--; // protected member + } + else { + status = IDLE; + } +} + +int Car::getSeatCount() const { + return seat_count; +} + +std::string Car::move() const { + return "Car drives on the road"; +} diff --git a/cpp_oop/src/Vehicle.cpp b/cpp_oop/src/Vehicle.cpp new file mode 100644 index 0000000..9dba07b --- /dev/null +++ b/cpp_oop/src/Vehicle.cpp @@ -0,0 +1,65 @@ +#include "Vehicle.h" +// Vehicle.cpp hava the function definition +// and variable initialization +// corresponding to Vehicle.h + +// 初始化extern過的variable +int global_vehicle_count = 0; + +Vehicle::Vehicle(int fuel, int max_speed, Color color) + : fuel(fuel), max_speed(max_speed), color(color), status(IDLE) { + global_vehicle_count++; // 每創建一個交通工具,總數+1 +} + +Vehicle::~Vehicle() { + global_vehicle_count--; // 交通工具被刪除時,總數-1 +} + +void Vehicle::refuel(int amount) { + status = REFUELING; + fuel += amount; + status = IDLE; +} + +int Vehicle::getFuel() const { + return fuel; +} + +int Vehicle::getMaxSpeed() const { + return max_speed; +} + +Color Vehicle::getColor() const { + return color; +} + +VehicleStatus Vehicle::getStatus() const { + return status; +} + +void Vehicle::setStatus(VehicleStatus new_status) { + status = new_status; +} + +// ===== 使用 enum 來判斷 ===== +std::string Vehicle::getColorName() const { + if (color == Color::RED) { + return "Red"; + } + else if (color == Color::GREEN) { + return "Green"; + } + else if (color == Color::BLUE) { + return "Blue"; + } + else if (color == Color::YELLOW) { + return "Yellow"; + } + else if (color == Color::BLACK) { + return "Black"; + } + else if (color == Color::WHITE) { + return "White"; + } + return "Unknown"; +} diff --git a/cpp_oop/src/main.cpp b/cpp_oop/src/main.cpp new file mode 100644 index 0000000..ff1d439 --- /dev/null +++ b/cpp_oop/src/main.cpp @@ -0,0 +1,54 @@ +#include +#include +#include "Car.h" +#include "Airplane.h" + +using namespace std; + +int main() { + cout << "===== C++ OOP Tutorial =====" << endl; + cout << "Topics: Header/Source files, enum, extern, OOP" << endl << endl; + + // ===== Topic 4: extern 全域變數 ===== + cout << "Global vehicle count: " << global_vehicle_count << endl; + + // ===== Topic 3: enum 使用 ===== + Color my_color = Color::RED; + if (my_color == Color::RED) { + cout << "Color is RED!" << endl; + } + + // ===== OOP: Polymorphism ===== + Car* v1 = new Car(100, 180, 5, Color::RED); + Airplane* v2 = new Airplane(300, 900, 1000, Color::BLUE); + // 也可以用smart pointer + // unique_ptr v1 = make_unique(100, 180, 5, Color::RED); + // unique_ptr v2 = make_unique(300, 900, 1000, Color::BLUE); + + cout << v1->move() << endl; + cout << v2->move() << endl; + + cout << "Car color: " << v1->getColorName() << endl; + cout << "Airplane color: " << v2->getColorName() << endl; + + cout << "Global count: " << global_vehicle_count << endl; + + // this method is inherited from Vehicle + cout << "Car Fuel: " << v1->getFuel() << endl; + cout << "Airplane maxSpeed: " << v2->getMaxSpeed() << endl; + + // these methods are additional function + cout << "Car SeatCount: " << v1->getSeatCount() << endl; + cout << "Airplane Altitude: " << v2->getAltitude() << endl; + + + // try on your own to call Car, Airplane's other function + + + // if use smart pointer, no need to delete, + // since system automatically release memory + delete v1; + delete v2; + + return 0; +} From 5a98ef61516c4311411518fa735839452fe9ebc2 Mon Sep 17 00:00:00 2001 From: chuangtsh Date: Sun, 28 Dec 2025 16:28:45 +0800 Subject: [PATCH 2/2] fix some comments --- cpp_oop/src/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp_oop/src/main.cpp b/cpp_oop/src/main.cpp index ff1d439..bd9bcbb 100644 --- a/cpp_oop/src/main.cpp +++ b/cpp_oop/src/main.cpp @@ -9,16 +9,16 @@ int main() { cout << "===== C++ OOP Tutorial =====" << endl; cout << "Topics: Header/Source files, enum, extern, OOP" << endl << endl; - // ===== Topic 4: extern 全域變數 ===== + // to see the initialization of extern global variable cout << "Global vehicle count: " << global_vehicle_count << endl; - // ===== Topic 3: enum 使用 ===== + // enum simple usage Color my_color = Color::RED; if (my_color == Color::RED) { - cout << "Color is RED!" << endl; + cout << "my Color is RED!" << endl; } - // ===== OOP: Polymorphism ===== + // OOP demo Car* v1 = new Car(100, 180, 5, Color::RED); Airplane* v2 = new Airplane(300, 900, 1000, Color::BLUE); // 也可以用smart pointer