Effective C++學(xué)習(xí)筆記(第四章)

條款18:讓接口容易被正確使用淳玩,不易被誤用
  • 建立新的類型作為函數(shù)可以防止用戶輸入錯誤的數(shù)據(jù)二汛,考察下面的類構(gòu)造函數(shù):
struct Date {
  Date(int day, int month, int year);
};

當(dāng)用戶調(diào)用構(gòu)造函數(shù)時侨糟,很容易輸入錯誤怠惶,比如將day的值當(dāng)成year的值耀态。這時候可以再創(chuàng)建Day轮傍,Month和Year新的數(shù)據(jù)類型:

struct Day {
  Day(int d) : val(d) {}
  int val;
};
struct Month {
  Month(int m) : val(m) {}
  int val;
};
struct Year {
  Year(int y) : val(y) {}
  int val;
};
// Date構(gòu)造函數(shù)以Day,Month首装,Year作為輸入
struct Date {
  Date(Month m, Day d, Year y);
};
  • 使用共享指針(shared pointer)作為函數(shù)返回值创夜,不僅可以避免用戶忘記delete指針造成的內(nèi)存泄露問題,還可以防止跨DLL delete問題仙逻。
條款19:設(shè)計class猶如設(shè)計type

設(shè)計一個class需要考慮以下問題:

  • 如何創(chuàng)建和銷毀對象
  • 構(gòu)造函數(shù)與賦值運(yùn)算操作是否有區(qū)別
  • 如果對象被值傳遞驰吓,涉及到哪些操作
  • type的合法值
  • 是否有繼承關(guān)系
  • 需要什么樣的轉(zhuǎn)換
  • 什么樣的操作符和函數(shù)對此新的type是合理的
  • delete掉哪些操作
  • 成員哪些為public涧尿,哪些為private
  • type的泛化性,是否定義一個具體的class還是一個class template
  • 是否真的需要定義一個新的type檬贰,是否可以通過已有type組合達(dá)到目的姑廉。
條款20:寧以pass-by-reference-to-const替換pass-by-value
  • 以引用方式傳遞參數(shù)通常比值傳遞方式更加高效,而且還可以避免對象切割問題偎蘸。
  • 內(nèi)置類型一般以值傳遞比較合理庄蹋,不適用此規(guī)則。
條款21:必須返回對象時迷雪,別妄想返回其reference
  • 如果返回的是一個函數(shù)內(nèi)部的局部對象限书,則切勿以引用方式返回,因為函數(shù)返回后章咧,該局部對象將會被析構(gòu)倦西。
條款22:將成員變量聲明為private
  • 將成員變量設(shè)置為private能夠提供更好的封裝性。
  • protected變量并不比public更具封裝性赁严。
條款23:寧以Non-member扰柠、Non-friend函數(shù)替換member函數(shù)
  • 考察一個類中的成員函數(shù),如果它的實現(xiàn)中不是必須要用類中的私有成員變量疼约,則建議將此函數(shù)不要作為類的成員函數(shù)卤档,而是以獨(dú)立的函數(shù)形式呈現(xiàn),函數(shù)的參數(shù)輸入即是該類的對象程剥。
條款24:若所有參數(shù)皆需類型轉(zhuǎn)換劝枣,請為此采用non-member函數(shù)。
  • 數(shù)據(jù)舉了一個復(fù)數(shù)相乘的例子:
class R {
public:
  const R operator*(const R& rhs) const;
};
R r1;

R r2 = r1 * 2; // 編譯OK
R r3 = 2 * r1; // 此時編譯不通過

編譯不通過的語句中织鲸,“2”如果在*號前面則不能進(jìn)行隱式轉(zhuǎn)換為一個R對象舔腾。
這時候,采用一個non-member的操作符就比較合適了搂擦。

const R operator*(const R& lhs, const R& rhs)
{
  ...
}
條款25:考慮寫一個不拋異常的swap函數(shù)
  • 在std空間內(nèi)有一個默認(rèn)的swap函數(shù)模板稳诚,它的定義如下:
namespace std {
template <typename T>
void swap(T& a, T& b)
{
    T tmp(a);
    a = b;
    b = tmp;
}
}

這里需要T類型對象支持operator = 操作。
考察以下類瀑踢,如果我們要對其兩個對象進(jìn)行swap操作扳还,將會出現(xiàn)一點效率的問題:

class MyImpl {
public:
private:
  std::vector<int> myVec;
};
class MyClass {
public:
  MyClass& operator=(MyClass& rhs) 
  {
    ...
    *(pImpl) = *(rhs.pImpl);
    ...  
}
private:
  MyImpl *pImpl;
};

MyClass obj1, obj2;

std::swap(obj1, obj2);  // 產(chǎn)生額外的拷貝操作,效率非常低

如果我們此時調(diào)用std::swap函數(shù)對MyClass對象進(jìn)行交換操作時橱夭,則會導(dǎo)致數(shù)據(jù)的拷貝普办,并且并沒有達(dá)到交換的目的。

此時需要在MyClass類中提供一個swap成員函數(shù)徘钥,實現(xiàn)真正的交換功能:

class MyClass {
public:
  void swap(const MyClass& rhs) 
  {
    std::swap(pImpl, rhs.pImpl);
  }
};

接下來就需要對std空間內(nèi)的swap函數(shù)針對MyClass類進(jìn)行特例化:

namespace std {
template <>   // 這里為空代表是對swap模板進(jìn)行特例化
void swap(MyClass& a, MyClass& b) noexcept
{
    a.swap(b);
}
}

int main()
{
  MyClass obj1, obj2;
  
  std::swap(obj1, obj2); // 調(diào)用上述特例化的版本,并且調(diào)用MyClass類中的swap成員函數(shù)肢娘,達(dá)到真正交換的目的呈础。

  return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舆驶,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子而钞,更是在濱河造成了極大的恐慌沙廉,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件臼节,死亡現(xiàn)場離奇詭異撬陵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)网缝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門巨税,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人粉臊,你說我怎么就攤上這事草添。” “怎么了扼仲?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵远寸,是天一觀的道長。 經(jīng)常有香客問我屠凶,道長驰后,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任矗愧,我火速辦了婚禮灶芝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘贱枣。我一直安慰自己监署,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布纽哥。 她就那樣靜靜地躺著钠乏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪春塌。 梳的紋絲不亂的頭發(fā)上晓避,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機(jī)與錄音只壳,去河邊找鬼俏拱。 笑死,一個胖子當(dāng)著我的面吹牛吼句,可吹牛的內(nèi)容都是我干的锅必。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼搞隐!你這毒婦竟也來了驹愚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤劣纲,失蹤者是張志新(化名)和其女友劉穎逢捺,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體癞季,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡劫瞳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了绷柒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片志于。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖辉巡,靈堂內(nèi)的尸體忽然破棺而出恨憎,到底是詐尸還是另有隱情,我是刑警寧澤郊楣,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布憔恳,位于F島的核電站,受9級特大地震影響净蚤,放射性物質(zhì)發(fā)生泄漏钥组。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一今瀑、第九天 我趴在偏房一處隱蔽的房頂上張望程梦。 院中可真熱鬧,春花似錦橘荠、人聲如沸屿附。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挺份。三九已至,卻和暖如春贮懈,著一層夾襖步出監(jiān)牢的瞬間匀泊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工朵你, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留各聘,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓抡医,卻偏偏與公主長得像躲因,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容