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
38 changes: 38 additions & 0 deletions cpp_oop/Makefile
Original file line number Diff line number Diff line change
@@ -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
110 changes: 110 additions & 0 deletions cpp_oop/README.md
Original file line number Diff line number Diff line change
@@ -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
```

23 changes: 23 additions & 0 deletions cpp_oop/include/Airplane.h
Original file line number Diff line number Diff line change
@@ -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
24 changes: 24 additions & 0 deletions cpp_oop/include/Car.h
Original file line number Diff line number Diff line change
@@ -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
60 changes: 60 additions & 0 deletions cpp_oop/include/Vehicle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// to avoid multiple include (include guard)
#ifndef VEHICLE_H
#define VEHICLE_H

#include <string>

// 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
23 changes: 23 additions & 0 deletions cpp_oop/src/Airplane.cpp
Original file line number Diff line number Diff line change
@@ -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";
}
24 changes: 24 additions & 0 deletions cpp_oop/src/Car.cpp
Original file line number Diff line number Diff line change
@@ -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";
}
65 changes: 65 additions & 0 deletions cpp_oop/src/Vehicle.cpp
Original file line number Diff line number Diff line change
@@ -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";
}
Loading