欲開發一個好的接口,首先必須考慮客戶可能做出什麼樣的錯誤。
class Date
{
public:
Date(int month, int day, int year);
... ...
};
- 他們也許會以錯誤的次序傳遞參數,如:Date d(30, 3, 1995);
- 他們可能傳遞一個無效的月份或天數,如:Date d(2, 30, 1995);
struct Day {
explicit Day(int d) : val(d) { }
int val;
};
struct Month{
explicit Month (int d) : val(d) { }
int val;
};
struct Year{
explicit Year (int d) : val(d) { }
int val;
};
class Date {
public:
Date(const Month& , const Day& d, const Year& y);
... ...
};
// 使用
Date d(30, 3, 1995); // error,類型錯誤
Date d(Day(30), Month(3), Year(1995)); // error,類型錯誤
Date d(Month(3), Day(30), Year(1995));
讓types容易被正確使用,不容易被誤用。
Inverstment* createInvestment();
std::tr1::shared_ptr<Investment> createInvestment();
//創建一個null shared_ptr指針,並自帶一個刪除器
std::tr1::shared_ptr<Investment> pInv(0, getRidOfInvestment); // error!第一個參數應該是一個指針,而不是int
// 使用轉換cast
std::tr1::shared_ptr<Investment> pInv( static_cast<Investment*>(0), getRidOfInvestment );
// 基於上面的定製的tr1::shared_ptr來解決上面的這個錯誤傾向
std::tr1::shared_ptr<Investment> createInvestment()
{
std::str1::shared_ptr<Investment> retVal(static_cast<Investment*>(0), getRidOfInvestment);
retVal = ... ; // 令retVal指向正確對象
return retVal;
}
- 好的接口很容易被正確使用,不容易被誤用。應該在接口設計時努力打到這點。
- 促進正確使用的辦法包括接口的一致性,以及與內置類型的行爲兼容
- 阻止誤用的辦法包括建立新類型、限制類型上的操作,束縛對象值,以及消除客戶的資源管理責任。
- tr1::shared_ptr支持定製刪除器,這可防範DLL問題,可被用來自動解除互斥鎖問題。(Effective C++(14) 在資源管理類中小心copying行爲)