//條款18:讓接口容易被正確使用,不易被誤用 // 1.若是客戶企圖使用某個接口而卻沒有得到他所預期的行爲,那麼這個代碼就不應經過編譯。 // 2.促進正確使用的方法包括接口的一致性,以及與內置類型的行爲兼容。 // 3.阻止誤用的方法包括創建新類型、限制類型上的操做,束縛對象值,以及消除客戶的資源管理責任。 // 4.shared_ptr支持自定義刪除器,能夠方便的用於管理各類資源。 //條款20:pass by reference to const 替換 pass by value // 1.C++的底層操做會將傳引用操做以指針的形式來實現。 // 2.傳遞const的引用能夠避免父對象接收子對象時候面臨的子對象被切割的問題。 // 3.傳遞const的引用能夠有效避免無謂的拷貝和銷燬操做,在性能上產生優點 // 4.對於內置類型以及STL的迭代器以及STL中的函數對象,對它們而言傳遞值比傳遞引用更加適當。對於此條規則,經vs2010測試發現,傳值與傳引用幾乎沒什麼差異,因此統一使用傳引用代替傳值是能夠的。 //條款22:將成員變量聲明爲private // 1.將成員變量聲明爲private的,這能夠賦予客戶訪問數據的一致性、可細微劃分訪問控制、允諾約束條件得到保證,並讓類的設計者以充分的實現彈性。 // 2.切記protected並不比public更具封裝性。若子類以public方式繼承,則能夠經過using輕鬆改變父類中protected成員的訪問權限。 //條款23:以非成員函數、非友元函數替換成員函數 // 1.越少的代碼能夠訪問到類的私有成員數據,那麼類的私有成員數據的封裝性就越好。 // 以下代碼:ClearCTestData()函數被聲明爲類的非成員函數,使得能訪問類的私有成員的函數減小,這就提升了類的數據的封裝性。如此當改變了類的數據成員的時候,須要被改變的代碼量就會減小。 class CTest { public: CTest() : value0(0), value1(0){} public: void ClearValue0(){value0 = 0;} void ClearValue1(){value1 = 0;} private: int value0; int value1; }; void ClearCTestData(CTest &Test) { Test.ClearValue0(); Test.ClearValue1(); } // 2.上述的ClearCTestData()系列函數,一般是做爲類的輔助工具提供的,將其聲明爲類的非成員函數,能夠下降編譯的依存性。 //條款24:若全部參數均可能須要類型轉換,那麼最好將其聲明爲類的非成員函數 //1.以下代碼: class CTest { public: CTest (int nTemValue) : value(nTemValue){} public: const CTest operator * (const CTest& tem) const {return CTest(value * tem.value);} //此處之因此不是返回一個引用而是按值返回一個對象,是爲了防止引用對象不存在的狀況。 int GetValue() const {return value;} //爲了使得常量對象也能調用此函數,必須將其聲明爲常量成員函數。 private: int value; }; const CTest FunTest(const CTest &tem0, const CTest &tem1) { return CTest(tem0.GetValue() * tem1.GetValue()); } CTest Test0(1); CTest Test1 = Test0 * 2; //容許經過編譯 //CTest Test2 = 2 * Test0; //不容許經過編譯 //之因此CTest Test1 = Test0 * 2;能經過編譯,是由於發生了隱式類型轉換,將2轉換爲CTest類型 //之因此CTest Test2 = 2 * Test0;不能經過編譯,是由於只有參數位於參數列表中,這個參數才能發生隱式類型轉換。 CTest Test2 = FunTest(2, 2); //容許經過編譯,須要隱式轉換的參數都位於形參列表中 //條款25:考慮爲類寫出一個不拋出異常的swap函數 // 1.swap是一個有趣的函數,本來是STL的一部分,然後來成爲異常安全性變成的脊柱,以及用來處理自我賦值的可能性。 // 2.當std::swap對自定義的類型效率不高的時候(好比在這個類型中使用了指針指向了一個內存,如此swap應該交換指針而非交換指針所指對象),提供一個swap成員函數,並肯定這個函數不拋出異常 // 3.若是提供一個成員函數swap,那麼也該提供一個非成員函數版本的swap來調用成員函數版本的swap。 // 4.不要試圖往std命名空間中添加新的成員,這種行爲是未定義的。