查漏補缺 類(C Primer)

2021-07-14 13:26:14 字數 3750 閱讀 3281

1、建構函式

(1)編譯器可以建立乙個合成的預設建構函式,為什麼我們還需要顯式建立建構函式?

原因有三:

(2)注意以下幾點:

(3)在什麼情況下必須使用建構函式初始值列表為成員提供初始值?

除了某些資料成員必須被初始化之外,還有底層效率的問題。使用初始化列表是在進入函式體前構造成員時同時進行初始化,而在函式體中賦值則是先在進入函式體前構造資料成員再在函式體中進行賦值操作。兩者的區別主要依賴於資料成員的型別。

注意:成員初始化的順序與初始化列表的順序無關,與他們在類中定義的順序一致。

(4)委託建構函式

舉個例子:

class sale_data

//其餘建構函式全部委託另乙個建構函式

sale_data():sale_data("",0,0){}

sale_data(std::string s):sale_data(s,0,0){}

sale_data(std::istream &is):sale_data()

};

當乙個建構函式委託給另乙個建構函式時,受委託的建構函式的初始值列表和函式體被一起執行。假如函式體包含有**的話,將先執行這些**,然後控制權才會交還給委託者的函式體。

(5)隱式的類型別轉換

能通過乙個實參呼叫的建構函式定義了一條從建構函式的引數型別向類型別隱式轉換的規則。這樣隱式的呼叫也稱作轉換建構函式

如(4)中定義的接受string和istream的建構函式分別定義了從這兩種型別向sale_data隱式轉換的規則。也就是說,在需要sale_data的地方,我們可以使用string或istream作為替代。

編譯器只會自動執行一次型別轉換,例如下面的**隱式地執行了兩種型別轉換,所以是錯誤的:

string null_book="999-9-9999";

item.combine(null_book);//使用null_book建立乙個sale_data物件,然後將臨時量傳遞給combine成員函式

item.combine("999-9-9999");//使用了兩種轉換規則,錯誤:將「999-9-9999」轉換為string,再將string轉換為sale_data物件

//正確的做法是如上第一條或者如下:

item.combine(string("999-9-9999"));//顯式轉換為string,隱式轉換為sale_data

item.combine(sale_data("999-9-9999"));//隱式轉為string,顯式轉為sale_data

若是使用explicit關鍵字對建構函式的宣告進行修飾,就會阻止建構函式定義的隱式轉換,將其宣告成顯式建構函式。

...

explicit sale_data(const std::string &s):bookno(s) {}

...//下面做法就是錯誤的,因為string對應的建構函式是explicit的

item.combine(null_book);

關鍵字explicit只對乙個實參的建構函式有效,需要多個實參的建構函式不能用於執行隱式轉換,所以無需將這些建構函式指定為explicit的。只能在類內宣告建構函式時使用explicit關鍵字,在類外定義時不應該重複。

當我們以explicit關鍵字宣告建構函式時,它將只能以直接初始化的形式(使用=)使用,而且,編譯器將不會在自動轉換的過程中使用該建構函式。儘管這樣,我們可以使用這樣的建構函式顯式地強制進行轉換:

item.combine(sale_data(null_book));//實參是乙個顯式構造的sale_data物件

2、聚合類

聚合類使得使用者可以直接訪問其成員,並且具有特殊的初始化語法形式。當乙個類滿足如下條件時,我們就說它是聚合的:

如:

struct data;

我們提供乙個花括號括起來的成員初始值列表用來初始化聚合類的資料成員,注意,初始值的順序必須與宣告的順序一致。 data vall=;

3、類的靜態成員

(1)宣告靜態成員

有的時候類需要它的一些成員與類本身直接相關,而不是與類的各個物件保持關聯。我們通過在成員宣告之間加上關鍵字static使得其與類關聯在一起。

靜態成員可以是public或private的,靜態成員函式不與物件繫結在一起也沒有了this指標

類的靜態成員存在於任何物件之外,物件中不包含任何與靜態資料成員有關的資料,靜態成員被所有的類物件共享。

(2)使用類的靜態成員

(3)定義靜態成員

我們可以在類的內部和外部定義靜態成員,當在類的外部定義靜態成員時,不能重複static關鍵字,該關鍵字只出現在類內部的宣告語句。在類的外部定義時要指明所屬類的作用域。

一般來說,我們不能在類的內部初始化靜態成員,相反的,必須在類的外部定義和初始化每個靜態成員,而且靜態成員只能定義一次。靜態成員和其他成員一樣可以訪問類的私有成員。一旦它被定義,就將一直存在於程式的整個生命週期中。

4、使用class和struct關鍵字

實際上我們可以使用這兩個關鍵字中的任何乙個定義類

唯一的區別是,struct預設的訪問許可權是public的,而class預設是private的。

5、友元

如果類想把乙個函式或類作為它的友元,只需要增加一條以friend關鍵字開頭的函式宣告語句即可。友元可以訪問類的非公有成員。

友元的宣告只能定義在類的內部,位置不限。但是友元的宣告僅僅是指定了訪問的許可權,而不是乙個通常意義上的函式宣告。我們必須在友元宣告之外再專門對函式進行一次宣告以提供函式可見。此外,友元函式可以定義在類的內部,這樣的函式是隱式內聯的。

為了使友元對類的使用者可見,我們通常把友元的單獨宣告與類本身放置在同乙個標頭檔案內。

注意:每個類負責控制自己的友元函式或友元類,友元關係不具有傳遞性。

如果乙個類想把一組過載函式宣告成為它的友元,它需要對這組函式中的每乙個單獨宣告,否則只能是對應版本的過載函式成為它的友元。

6、常量成員函式

在成員函式宣告的後面加上const,意味著這個成員函式不能修改物件的普通(既不是static也不是mutable)資料成員。const成員的this指標是指向常量的指標,通過區分函式是否是const可以進行過載。

如果在資料成員宣告前加上mutable關鍵字,則該資料成員成為可變資料成員。乙個可變資料成員永遠不會是const,即使它是const物件的成員。但是乙個const成員函式可以改變乙個可變成員的值。

7、不完全型別

已經宣告但是尚未定義的型別

不完全型別不能用於定義變數或者類的成員,但是用不完全型別定義指標或引用是合法的,也可以宣告(但是不能定義)以不完全型別作為引數或者返回型別的引數。

比如我們可以僅僅先宣告乙個類而不定義它,這種宣告是前向宣告,在它宣告後定義前是乙個不完全型別。

對於乙個類來說,我們必須首先完成類的定義,編譯器才能知道儲存該資料成員需要多少記憶體空間。因為只要當類全部完成後才算是被定義,所以乙個類的成員型別不能是該類自己。然而,一旦乙個類的名字出現後,它就被認為宣告過了(但是尚未定義),因此類允許包含指向它自身型別的引用或指標或作為引數或返回型別的引數。

DOM查漏補缺

使用getattribute 方法只能獲取屬性的文字內容,比如script或者style就不方便了,因此建議使用屬性的方法來獲取,即elenode.attr這種形式 但是自定義的標籤屬性必須使用getattribute 方法來獲得。屬性的方法會返回undefined 修改class通過屬性名的方法是...

CSS查漏補缺

從父類繼承 padding inherit 字母大寫 小寫,首字母大寫 h1 h2 credits 字母 漢字間距 letter spacing 0.2em 文字對齊方向 text align right 鏈結下劃線aa hover 首字母 首行 p.intro first letter p.int...

查漏補缺 1

1.alert 用來顯示一段文字。不是文字強制轉換為文字。2.sort 排序,原理是根據unicode進行排序,可接受乙個比較函式。比較函式 function compare a,b else if a b else var values 0,5,10,5,65 values.sort compar...