[C++ Primer Note6] 類

  1. 成員函數(shù)一個(gè)名為this的額外隱式參數(shù)來訪問調(diào)用它的那個(gè)對(duì)象。當(dāng)我們調(diào)用一個(gè)成員函數(shù)時(shí)拱烁,編譯器負(fù)責(zé)把對(duì)象的地址傳遞給隱式參數(shù)this籽懦。this實(shí)際上是一個(gè)常量指針,不允許改變this中的地址镐作。
  2. 跟隨在成員函數(shù)參數(shù)列表之后的const關(guān)鍵字表示this是一個(gè)指向常量的指針招拙。這種使用const的成員函數(shù)被稱作常量成員函數(shù)(const member function)
  3. 常量對(duì)象以及常量對(duì)象的引用或指針都只能調(diào)用常量成員函數(shù)洞斯。
  4. 類本身就是一個(gè)作用域朗徊,類的成員函數(shù)的定義嵌套在類的作用域之內(nèi)报慕,成員函數(shù)可以隨意使用類中的其他成員而無須在意出現(xiàn)次序蝠嘉。
  5. 在類的外部定義成員函數(shù)時(shí)缘回,成員函數(shù)的定義必須與它的聲明匹配秽誊,如果成員函數(shù)被聲明為常量成員函數(shù)错览,那么定義也必須在參數(shù)列表后指定const屬性
  double Sales_data::avg_price() const{
    .....
  }
  1. 可以通過*this來返回執(zhí)行該成員函數(shù)的對(duì)象
  2. 類的成員通常需要定義一些輔助函數(shù)理澎,這些函數(shù)定義的操作概念上屬于類的接口的組成部分逞力,但實(shí)際上不屬于類的本身。這些函數(shù)的聲明一般應(yīng)與類聲明在同一個(gè)頭文件內(nèi)矾端。
  3. 類通過一個(gè)或幾個(gè)特殊的成員函數(shù)來控制其對(duì)象的初始化過程掏击,這些函數(shù)叫做構(gòu)造函數(shù)(constructor),構(gòu)造函數(shù)名字和類名相同秩铆,但是沒有返回類型砚亭。
  4. 構(gòu)造函數(shù)不能被聲明為const的,當(dāng)我們創(chuàng)建一個(gè)類的const對(duì)象時(shí)殴玛,直到構(gòu)造函數(shù)完成初始化過程捅膘,對(duì)象才能真正取得“常量”屬性。因此滚粟,構(gòu)造函數(shù)在const對(duì)象的構(gòu)造過程中可以向其寫值寻仗。
  5. 類通過一個(gè)特殊的構(gòu)造函數(shù)來控制默認(rèn)初始化過程,這個(gè)函數(shù)叫做默認(rèn)構(gòu)造函數(shù)(default constructor)凡壤,默認(rèn)構(gòu)造函數(shù)無需任何實(shí)參署尤。
  6. 如果我們的類沒有顯式定義構(gòu)造函數(shù)耙替,編譯器就會(huì)隱式地定義一個(gè)默認(rèn)構(gòu)造函數(shù),又被稱為合成的默認(rèn)構(gòu)造函數(shù)(synthesized default constructor)曹体,對(duì)大多數(shù)類型來說俗扇,這個(gè)函數(shù)按照如下規(guī)則初始化類的數(shù)據(jù)成員;
  • 如果存在類內(nèi)初始值箕别,用它來初始化成員铜幽。
  • 否則,默認(rèn)初始化該成員串稀。
  1. 對(duì)于一個(gè)普通的類來說除抛,必須定義它自己的默認(rèn)構(gòu)造函數(shù)。
  2. 如果類中包含其他類類型的成員且該成員的類型沒有默認(rèn)構(gòu)造函數(shù)母截,那么編譯器將無法生成默認(rèn)構(gòu)造函數(shù)到忽。
  3. C++11標(biāo)準(zhǔn)中,如果我們需要默認(rèn)的行為微酬,那么可以通過在參數(shù)列表后面寫上=default來要求編譯器生成構(gòu)造函數(shù)绘趋。
  Sales_data() = default;

=default既可以和聲明一起在類的內(nèi)部,也可以作為定義在類的外部颗管。和其他函數(shù)一樣,如果在類的內(nèi)部滓走,則默認(rèn)構(gòu)造函數(shù)是內(nèi)聯(lián)的垦江;如果它在類的外部,則默認(rèn)情況下不是內(nèi)聯(lián)的搅方。

  1. 構(gòu)造函數(shù)初始值列表(constructor initialize list)負(fù)責(zé)為新創(chuàng)建的對(duì)象的一個(gè)或幾個(gè)數(shù)據(jù)成員賦初值比吭。
  Sales_data(const string &s):bookNo(s),units_sold(0),revenue(0){}
  1. 沒有出現(xiàn)在構(gòu)造函數(shù)初始值列表中的成員將通過相應(yīng)的類內(nèi)初始值(如果存在的話)初始化,或者執(zhí)行默認(rèn)初始化姨涡。如果不支持類內(nèi)初始值衩藤,則所有構(gòu)造函數(shù)都應(yīng)該顯式地初始化每個(gè)內(nèi)置類型的成員
  2. 除了定義類的對(duì)象如何初始化外涛漂,類還需要控制拷貝赏表,賦值銷毀對(duì)象時(shí)發(fā)生的行為匈仗。對(duì)象在幾種情況下會(huì)被拷貝瓢剿,如我們初始化變量以及以值得方式傳遞或返回一個(gè)對(duì)象等。如果我們不主動(dòng)定義這些操作悠轩,編譯器將替我們合成它們间狂。一般來說,生成的版本將對(duì)對(duì)象的每個(gè)成員執(zhí)行拷貝火架,賦值和銷毀操作鉴象。
  3. 一個(gè)類可以包括0個(gè)或多個(gè)訪問說明符(public忙菠,private)
  4. 使用classstruct定義類唯一的區(qū)別就是默認(rèn)的訪問權(quán)限。struct默認(rèn)為public纺弊,而class默認(rèn)為private
  5. 類可以允許其他類或者函數(shù)訪問它的非公有成員牛欢,方法是令其他類或者函數(shù)成為它的友元(friend)。如果類想把函數(shù)作為它的友元俭尖,只需要增加一條以friend關(guān)鍵字開始的函數(shù)聲明語句即可:
  class Sales_data{
    friend Sales_data add(const Sales_data&, const Sales_data&);
    ...
}

友元聲明只能出現(xiàn)在類定義的內(nèi)部氢惋,但是具體位置不限。友元不是類的成員也不受區(qū)域訪問控制級(jí)別的約束稽犁。一般來說焰望,最好在類定義開始結(jié)束前的位置集中聲明友元。

  1. 友元的聲明僅僅指定了訪問的權(quán)限已亥,而非一個(gè)通常意義上的函數(shù)聲明熊赖。如果我們希望類的用戶能夠調(diào)用某個(gè)友元函數(shù),那么我們就必須在友元聲明之外再專門對(duì)函數(shù)進(jìn)行一次聲明虑椎。
  2. 除了定義數(shù)據(jù)和函數(shù)成員之外震鹉,類還可以自定義某種類型在類中的別名,其也存在訪問限制捆姜,可以是public或private传趾。
class Screen{
public:
  typedef string::size_type pos;
  ....
}

用來定義類型的成員必須先定義后使用,因此類型成員通常出現(xiàn)在類開始的地方泥技。

  1. 定義在類內(nèi)部的函數(shù)是默認(rèn)內(nèi)聯(lián)的浆兰,也可以在類的內(nèi)部或外部用inline顯式聲明成員函數(shù)。不過珊豹,最好只在類外部定義的地方說明inline簸呈,便于理解。
  2. 如果我們希望修改類的某個(gè)數(shù)據(jù)成員店茶,即使是在一個(gè)const成員函數(shù)內(nèi)蜕便,可以通過在變量的聲明中加入mutable關(guān)鍵字。
  3. 可以通過是否為const實(shí)現(xiàn)多個(gè)成員函數(shù)的重載版本贩幻,這樣轿腺,const對(duì)象會(huì)調(diào)用const版本,非常量對(duì)象則調(diào)用非const版本段直。
  4. 我們可以把類名作為類型的名字使用吃溅,或者我們也可以把類名跟在關(guān)鍵字class或struct后面:
  Sales_data item1;
  class Sales_data item1;     //一條等價(jià)的聲明
  1. 就像可以把函數(shù)的聲明和定義分離開一樣,我們也能僅聲明類而暫時(shí)不定義它:
  class Screen;
  1. 除了把非成員函數(shù)定義為友元之外鸯檬,類還可以把其他類定義成友元决侈,也可以把其他類(之前已定義過的)的成員函數(shù)定義成友元。
class Screen{
  friend class Window_mgr;
  ...
}

如果指定了友元類,則友元類的成員函數(shù)可以訪問此類所有成員赖歌。

class Screen{
  friend void Window_mgr::clear();
  ...
}

要想令某個(gè)成員函數(shù)成為友元枉圃,需要仔細(xì)組織程序的結(jié)構(gòu)以滿足聲明和定義的彼此依賴關(guān)系

  • 先定義友元函數(shù)所屬的類,聲明友元函數(shù)但不定義
  • 定義需要友元函數(shù)的類庐冯,包括對(duì)友元函數(shù)的友元聲明
  • 最后定義友元函數(shù)孽亲,因?yàn)檫@樣才能使用另一個(gè)類的成員。
  1. 類和非成員函數(shù)的聲明不是必須在它們的友元聲明之前展父。當(dāng)一個(gè)名字出現(xiàn)在一個(gè)友元聲明時(shí)返劲,我們隱式地假定改名字在當(dāng)前作用域中是可見的。友元函數(shù)可以在類的內(nèi)部定義栖茉,但仍必須在類的外部提供相應(yīng)的聲明篮绿。本質(zhì)上友元聲明的作用是影響訪問權(quán)限,本身并非普通意義上的聲明吕漂。
  2. 一個(gè)類就是一個(gè)作用域亲配,所以我們在類外部定義成員函數(shù)必須同時(shí)提供類名和函數(shù)名。一旦遇到類名惶凝,定義的剩余部分就在類的作用域之內(nèi)了吼虎,所以可以直接使用類的成員。
  3. 類的定義分兩步處理:
  • 編譯成員的聲明
  • 直到類全部可見才編譯函數(shù)體
    但是對(duì)于聲明使用的名字苍鲜,包括返回類型和參數(shù)思灰,都必須在聲明前確保可見混滔。如果某個(gè)成員的聲明使用了類中尚未出現(xiàn)的名字官辈,編譯器會(huì)在定義該類的作用域中(類定義之前)繼續(xù)查找。
  1. 如果類中成員使用了外層作用域中的某個(gè)名字遍坟,而該名字代表一種類型,則類不能在之后重新定義該名字晴股。
  2. 類型名的定義通常出現(xiàn)在類開始的地方愿伴,確保所有該類型的成員都出現(xiàn)在定義之后。
  3. 如果成員函數(shù)在外部定義电湘,則它還會(huì)考慮在成員函數(shù)定義之前和類定義之后的作用域中的聲明隔节。
  4. 如果沒有在構(gòu)造函數(shù)的初始值列表中顯式地初始化成員,則該成員將在構(gòu)造函數(shù)體之前執(zhí)行默認(rèn)初始化寂呛。即使在構(gòu)造函數(shù)中顯式賦值也并不是初始化而是賦值怎诫。
  5. 成員的初始化順序與它們在類定義中出現(xiàn)順序一致
  6. 如果一個(gè)構(gòu)造函數(shù)為所有參數(shù)都提供了默認(rèn)實(shí)參,則它也實(shí)際上定義了默認(rèn)構(gòu)造函數(shù)贷痪。
  7. C++11標(biāo)準(zhǔn)使得我們可以定義所謂的委托構(gòu)造函數(shù)幻妓,即使用所屬類的其他構(gòu)造函數(shù)執(zhí)行它自己的初始化過程。
  class Sales_data{
    Sales_data():Sales_data("",0,0){}
    ...  
};

受委托的構(gòu)造函數(shù)的初始值列表和函數(shù)體被依次執(zhí)行劫拢,然后控制權(quán)才會(huì)交還給委托者的函數(shù)體肉津。

  1. 我們能夠?yàn)轭惗x隱式轉(zhuǎn)換機(jī)制强胰,如果構(gòu)造函數(shù)只接受一個(gè)實(shí)參,則它實(shí)際上定義了轉(zhuǎn)換為此類類型的隱式轉(zhuǎn)換機(jī)制妹沙,有時(shí)我們把這種構(gòu)造函數(shù)稱為轉(zhuǎn)換構(gòu)造函數(shù)偶洋。但需要注意的是:編譯器只會(huì)自動(dòng)地執(zhí)行一步類型轉(zhuǎn)換
  2. 我們可以通過將構(gòu)造函數(shù)聲明為explicit阻止隱式轉(zhuǎn)換。此時(shí)該構(gòu)造函數(shù)只能以直接初始化的形式使用距糖,即圓括號(hào)的形式玄窝。
  3. 聚合類使得用戶可以直接訪問其成員,當(dāng)一個(gè)類滿足一下條件時(shí)悍引,我們說它是聚合的:
  • 所有成員都是public
  • 沒有定義任何構(gòu)造函數(shù)
  • 沒有類內(nèi)初始值
  • 沒有基類恩脂,也沒有virtual函數(shù)
struct Data {
  int ival;
  string s;
};

我們可以提供一個(gè)花括號(hào)括起來的成員初始值列表來初始化聚合類的數(shù)據(jù)成員

Data vall={0,"Kevin"};
  1. 通過在成員聲明之前加上static關(guān)鍵字使得其與類關(guān)聯(lián)在一起,稱為靜態(tài)成員吗铐。
  2. 我們既可以在類的內(nèi)部也可以在類的外部定義靜態(tài)成員函數(shù)东亦,擋在外部定義時(shí),不能重復(fù)static關(guān)鍵字唬渗,該關(guān)鍵字只出現(xiàn)在類內(nèi)部的聲明語句典阵。
  3. 因?yàn)殪o態(tài)數(shù)據(jù)成員不屬于類的任何一個(gè)對(duì)象,所以它們并不是在創(chuàng)建類的對(duì)象時(shí)被定義的镊逝。一般來說壮啊,我們不能在類的內(nèi)部初始化靜態(tài)成員。
  4. 通常情況下撑蒜, 靜態(tài)成員不應(yīng)該在類的內(nèi)部初始化歹啼。然而,我們可以為靜態(tài)成員提供const整數(shù)類型的類內(nèi)初始值座菠,不過要求靜態(tài)成員必須是constexpr狸眼。
  5. 靜態(tài)成員的類型可以就是它所屬的類類型,而非靜態(tài)成員不行浴滴。同時(shí)靜態(tài)成員可以作為默認(rèn)實(shí)參拓萌。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市升略,隨后出現(xiàn)的幾起案子微王,更是在濱河造成了極大的恐慌,老刑警劉巖品嚣,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炕倘,死亡現(xiàn)場離奇詭異,居然都是意外死亡翰撑,警方通過查閱死者的電腦和手機(jī)罩旋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瘸恼,你說我怎么就攤上這事劣挫。” “怎么了东帅?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵压固,是天一觀的道長。 經(jīng)常有香客問我靠闭,道長帐我,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任愧膀,我火速辦了婚禮拦键,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘檩淋。我一直安慰自己芬为,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布蟀悦。 她就那樣靜靜地躺著媚朦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪日戈。 梳的紋絲不亂的頭發(fā)上询张,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音浙炼,去河邊找鬼份氧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛弯屈,可吹牛的內(nèi)容都是我干的蜗帜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼资厉,長吁一口氣:“原來是場噩夢啊……” “哼钮糖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起酌住,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎阎抒,沒想到半個(gè)月后酪我,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡且叁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年都哭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡欺矫,死狀恐怖纱新,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情穆趴,我是刑警寧澤脸爱,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站未妹,受9級(jí)特大地震影響簿废,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜络它,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一族檬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧化戳,春花似錦单料、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至盟步,卻和暖如春藏斩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背却盘。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來泰國打工狰域, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人黄橘。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓兆览,卻偏偏與公主長得像,于是被迫代替她去往敵國和親塞关。 傳聞我的和親對(duì)象是個(gè)殘疾皇子抬探,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

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