繼承是 C++ 實現 **IS-A** 關係、程式碼重用與多態的核心機制。本文以 Animal 基類與 Fish 衍生類為例,完整說明繼承語法、public 繼承語意、建構函數/解構函數調用順序,並驗證「父類先建構、子類後建構;解構順序相反」的鐵律。
class Animal { // 基類 / 父類
public:
void eat() { cout << "animal eat\n"; }
void sleep() { cout << "animal sleep\n"; }
void breathe(){ cout << "animal breathe\n"; }
};
class Fish : public Animal { // 衍生類 / 子類,public 繼承
// 無自有成員,繼承 Animal 所有 public/protected 成員
};
int main() {
Animal an; Fish fh;
an.eat(); // animal eat
fh.eat(); // animal eat (繼承而來)
}
public 繼承:基類 public 成員在衍生類保持 public,**IS-A 關係** (Fish *是一個* Animal)。protected 成員:衍生類可存取,外部不可存取。private 成員:衍生類**不可直接存取** (但佔記憶體、隨物件建構/解構)。
class Animal {
public:
Animal() { cout << "animal construct\n"; }
~Animal() { cout << "animal destruct\n"; }
// ...
};
class Fish : public Animal {
public:
Fish() { cout << "fish construct\n"; }
~Fish() { cout << "fish destruct\n"; }
};
int main() {
Fish fh;
}
animal construct
fish construct
fish destruct
animal destruct
+------------------+
| Animal 部分 | ← 基類子物件 (vptr 若有虛函數)
| - 成員變數 |
+------------------+
| Fish 部分 | ← 衍生類自有成員
| - 成員變數 |
+------------------+
```
Fish* 指向整個區塊起始;轉型為 Animal* 仍指向同一位址 (單一繼承無位移)。
若基類**無預設建構函數** (僅有帶參數版),衍生類**必須**在成員初始化清單顯式呼叫:
class Animal {
public:
Animal(int h, int w) { cout << "animal construct h="<
同樣適用於**初始化 const 成員**或**參考成員**:
class Point {
const int x, y;
public:
Point(int a, int b) : x(a), y(b) {} // 唯一初始化管道
};
| 基類成員 | public 繼承 | protected 繼承 | private 繼承 |
|---|---|---|---|
| public | public | protected | private |
| protected | protected | protected | private |
| private | 不可存取 | 不可存取 | 不可存取 |