做者:LogMsegmentfault
本文原載於 https://segmentfault.com/u/logm/articles,不容許轉載~安全
對象切割(slicing):當派生類對象以 by-value 方式傳遞參數並被視爲基類對象,基類的拷貝構造函數在構造時會把派生類特有的性質抹除。
"引用"在編譯器底層的實現就是指針(指針的本質是int類型的變量),因此在如下場景,"引用"並不必定比pass-by-value快:a. C++內置類型;b. STL的迭代器(底層實現是指針);c. 函數對象(底層實現是指針)。
做者的說法有必定道理,但我不徹底贊成做者的觀點:cookie
class WebBrowser { public: ... void clearCache(); void clearHistory(); void clearCookies(); ... } //假如如今要寫一個函數clearEverything(),做用是同時清理cache、history、cookies。 //使用member函數的狀況 class WebBrowser { public: ... void clearEverything(); ... } void WebBrowser::clearEverything() { clearCache(); clearHistory(); clearCookies(); } //使用non-member函數的狀況 void clearBrower(WebBrowser& wb) { wb.clearCache(); wb.clearHistory(); wb.clearCookies(); }
//第一種狀況:乘法函數爲member函數 class Rational { public: ... Rational(int numerator, int denominator); Rational(int num); //這個構造函數使得該類支持從int到Rational的類型轉換。若是前面加explict則說明不支持隱式類型轉換僅支持顯式轉換,如今沒加,支持隱式轉換 const Rational operator* (const Rational& rhs) const; } //使用 Rational lhs(1, 9); Rational result; result = lhs * 2; //ok,2不是Rational類型,但能夠發生隱式類型轉換 result = 2 * lhs; //bad,2不是Rational類型
//第二種狀況:乘法函數爲non-member函數 class Rational { public: ... Rational(int numerator, int denominator); Rational(int num); //這個構造函數使得該類支持從int到Rational的類型轉換 } const Rational operator* (const Rational& lhs, const Rational& rhs) { ... } //使用 Rational lhs(1, 9); Rational result; result = lhs * 2; //ok,2不是Rational類型,但能夠發生隱式類型轉換 result = 2 * lhs; //ok,2不是Rational類型,但能夠發生隱式類型轉換
std::swap
的典型實現以下代碼,這個實現比較平淡。對於某些類,寫一個模板特化的swap執行效率會更高。做者介紹了怎麼本身寫std::swap
的特化版本,這邊就不展開了。namespace std { //平淡的std::swap實現 template<typename T> void swap(T& a, T& b) { T temp(a); a = b; b = temp; } }