การเขียนโปรแกรมเชิงวัตถุ (OOP)
C++ มี class และ virtual function โดยตรง ส่วน C ใช้ struct และ function pointer
การเขียนโปรแกรมเชิงวัตถุใน C++ คืออะไร?
OOP จัดโปรแกรมรอบออบเจ็กต์ที่มีสถานะ invariant และพฤติกรรม C++ มี class, access control, inheritance และ virtual dispatch ส่วน C ต้องสร้างอย่างชัดเจน
หลักสำคัญสี่ข้อของ OOP
- Encapsulation ปกป้อง invariant ด้วยการควบคุมสถานะภายใน
- Abstraction เปิดเผย public interface ขนาดเล็ก
- Inheritance ทำให้สัญญาของ base class มีความเฉพาะเจาะจง
- Polymorphism เลือกพฤติกรรมจริงผ่าน virtual call
C และ C++ แสดงการออกแบบอย่างไร
C
C รวม struct กับ function pointer และใช้ข้อตกลงกับ API ดูแล invariant และ ownership
C++
C++ ใช้ private state, inheritance และ override โดย compiler ตรวจสอบ
คำแนะนำ: base class แบบ polymorphic ควรมี virtual destructor หลีกเลี่ยง raw pointer ที่เป็นเจ้าของและเลือก composition ก่อน
ตัวอย่างโค้ด C และ C++
main.c
#include <stdio.h>
typedef struct Account Account;
typedef void (*MonthEnd)(Account *account);
struct Account {
const char *owner;
double balance;
double interest_rate;
MonthEnd month_end;
};
void standard_month_end(Account *account) {
(void)account;
}
void savings_month_end(Account *account) {
account->balance *= 1.0 + account->interest_rate;
}
void print_account(Account *account) {
account->month_end(account);
printf("%s: %.2f\n", account->owner, account->balance);
}
int main(void) {
Account accounts[] = {
{"Ada", 150.0, 0.0, standard_month_end},
{"Lin", 200.0, 0.05, savings_month_end}
};
for (int i = 0; i < 2; ++i) {
print_account(&accounts[i]);
}
return 0;
}
Ada: 150.00
Lin: 210.00
C++
main.cpp
#include <iomanip>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
class Account {
std::string owner_;
double balance_;
protected:
void add_balance(double amount) { balance_ += amount; }
public:
Account(std::string owner, double balance)
: owner_(std::move(owner)), balance_(balance) {}
virtual ~Account() = default;
virtual void month_end() {}
const std::string& owner() const { return owner_; }
double balance() const { return balance_; }
};
class SavingsAccount final : public Account {
double interest_rate_;
public:
SavingsAccount(std::string owner, double balance, double rate)
: Account(std::move(owner), balance), interest_rate_(rate) {}
void month_end() override {
add_balance(balance() * interest_rate_);
}
};
int main() {
Account standard("Ada", 150.0);
SavingsAccount savings("Lin", 200.0, 0.05);
std::vector<Account *> accounts{&standard, &savings};
std::cout << std::fixed << std::setprecision(2);
for (Account *account : accounts) {
account->month_end();
std::cout << account->owner() << ": "
<< account->balance() << '\n';
}
}
Ada: 150.00
Lin: 210.00
เปรียบเทียบ C และ C++
C เก็บสถานะและ function pointer ใน struct ส่วน C++ เก็บยอดเงินเป็น private สืบทอดอินเทอร์เฟซและ override virtual function โค้ดฝั่งเรียกไม่ต้องตรวจชนิดจริง
C
C ใช้ prefix, callback, macro และ context struct
C++
ภาษาให้ abstraction ที่มี scope และ type-safe
แบบฝึกหัด
รันทั้งสองเวอร์ชันแล้วแก้ไขเพื่อสังเกตความแตกต่างของภาษา
- เขียนกลไก C ก่อน
- แทน manual cleanup ด้วย RAII
- ตรวจ allocation และ virtual dispatch