上月專欄介紹計算日期間隔的函數,本月改用 C++ 物件導向方法解決同一問題。核心在於創建新資料型別,使其行為如內建型別般自然——從「我想怎麼做」的函數導向,轉向「我的問題領域有哪些物件」的物件導向思維。
類別除定義資料成員,可加入成員函數。日期類別定義(date.h):
class Date {
int month, day, year;
public:
Date(); // 預設建構
Date(int m, int d, int y); // 多參數建構
Date interval(const Date& d2) const; // 計算間隔
// 存取器
int get_month() const { return month; }
int get_day() const { return day; }
int get_year() const { return year; }
};
:: 作用域運算子指明成員隸屬。& 參數為參考傳遞,避免複製大物件。result = d1.interval(d2);typedef struct Date Date;。Date::Date() { month=1; day=1; year=1970; } // 預設
Date::Date(int m, int d, int y) { month=m; day=d; year=y; }
Date d; 呼叫預設建構;Date d(10,1,51); 呼叫多參數建構。物件定義可出現在任何區塊,支援延遲建構。
將簡單成員函數移入類別定義內成內聯(如 isleap),兼具巨集展開效率與函數型別檢查、作用域規則。C++ 中除預處理器字串化/標記連接外,不需函數式巨集。
成員函數內無前綴的成員名(如 year)隱含指向呼叫物件(d1.year)。可用 this->year 明確表達,但鮮用。
直接存取 d1.month = 20; 會導致無效狀態。解決:將資料設為 private,提供 const 存取器:
class Date {
private:
int month, day, year;
public:
int get_month() const { return month; }
// ...
Date interval(const Date&) const; // const 成員不修改物件
};
改用 class 關鍵字(預設 private)取代 struct,更符合封裝慣例。
參考是物件別名,宣告即初始化,不可重新綁定,無需 &/* 操作,可視為「自動解參考的 const 指標」。
void swap(int&, int&) 實現真正交換。void f(const BigType&) 避免複製開銷。func() = value; 將函數呼叫置於賦值左側。int& current() { return a[index]; }
current() = 10; // 修改 a[0]
將整合輸入輸出流、靜態成員、運算子多載,完成功能完備的日期類別。