---
# System prepended metadata

title: API design for C++ 筆記

---

# API design for C++ 筆記

## API 定義

C++ API 通常包含如下

1. Header
2. lib
3. document

### 用 API 的理由

* 隱藏實作
* 提高壽命
* 模組化
* 減少重複
* 移除 hardcode
* 易於改變
* 易於優話
* 平行開發

### 不用 API 的理由

* license 限制
* 功能不符合
* no source code
* no document

> 註： SDK 是裝來用 API 的，並非 API 本身


## 品質

:::info
永遠不要假設使用者會正常的使用或擴展 API
:::

### 提供良好的抽象

物件導向要學好

N 對 N 的關係要搞清楚

### 隱藏實作

1. 物理隱藏
	* 將實作跟界面用 .h 和 .cpp 分開
2. 邏輯隱藏
	* 限制邏輯上的存取權限
	* public 誰都可以拿
	* protected 自己跟子可以拿
	* private 自己可以拿

> 註：friend 是特例，慎用

#### 隱藏成員變數

善用 getter/setter 好處有很多如下：
* 驗證數值正確性
* 延遲多餘的運算
* 快取常用的運算
* 自動進行附加的操作
* 自動對外通知
* 除錯(assert)
* thread safe
* 存取控制
* 維持內部相依性

> 註：class 的資料成員應該永遠是 private
> 此外切勿返回內部成員的非 const reference or pointer

更激進一點甚至應該用 pimpl 的方式在 .h 檔中隱藏你的 private 成員，順便加速編譯。

### 保持 API 的簡單

存在價值有疑問的東西就不該存在，過早的最佳化是弊端

### 審慎的增加 virtual function

virtual function 有以下缺點
* non inline
* 無法預期 base class 的改變對 user 的影響，導致結構脆弱
* override 的實作無法預期

所有 virtual function 都應該是 private 的，繼承需要才可以是 protect。

還要注意以下事項
1. 解構子一定要是 virtual，才能確保釋放子類別的額外資源。
2. 紀錄內部呼叫順序，這樣使用者才知道實作時需要呼叫什麼方法來保持內部相依性。
3. 切勿從建構或解構子內呼叫 virtual function，這些呼叫無法被指到子類別的實作。

> 註：除非有強而有力的理由，否則別使用 virtual