12 類

1. 類的定義和聲明

  1. 一旦類定義完成後,就沒有任何方式可以增加成員了。

  2. 在類內部定義的成員函數(函數實現體在類中),則會認爲是inline成員函數(該函數被調用時直接換成函數體)

  3. 不完全類型:聲明瞭該類,在定義該類之前,成爲不完全類型:
    • 只有當類定義體完成之後才能定義類,所以類不能具有自身類型的數據成員(因爲該類定義還沒有完成,不知道存儲該類的對象所需的空間,無法完成初始化)
    • 類數據成員可以是指向自身類型的指針或引用,因爲指針或者引用僅僅是一個地址空間或者別名,所以分配空間與該類無關,所以可以有。
  4. 類的定義必須以分號結束,因爲類的定義之後可以接受對象定義列表。
  5. mutable關鍵字: 數據成員是可變的(在const成員函數內也可變)。

2. this指針

  1. this指針和調用成員函數的對象綁定在一起;

  2. this指針是一個const指針,即指針本身不能改變,但是指向的內容可以改變(易理解,this和對象關聯,對象本身在函數調用過程中不能改變,但是對象中的數據成員可以改變)

    • const 成員函數不能改變其所操作的對象的數據成員,是隻讀函數。並且必須在聲明和定義中均出現,不然會有編譯錯誤。
    • 由上知,const成員函數既不能改變this所指內容,也不能改變this地址。

3. 類作用域

  1. 在類作用域外(即分號結束),定義類的數據成員和函數定義均需要指明屬於哪個類(完全限定名)

    • 形參和函數體中可以不指明類直接用類的數據成員,因爲函數名字已經指明瞭屬於哪一個類;
    • 函數返回類型在函數名之前,在遇到函數返回類型的時候不知道屬於哪個類,所以如果函數返回類型用到了類中定義的某一個類型,則需要指明完全限定名。
  2. 類定義分爲兩個階段:

    • 編譯成員聲明;
    • 只有在所有成員出現之後,編譯它們的定義本身。
  3. 名字查找

    • 在改名字的塊(函數作用域)中查找;
    • 在所屬類成員(類作用域)的聲明;
    • 在外圍作用域查找(如全局變量)等等。

4. 構造函數

  1. 構造函數不能聲明爲const類型, 因爲const函數除mutable數據成員外其他數據成員是不可改變的,而構造函數就是給成員函數賦值的,兩者相悖,所以error。

  2. 構造函數過程:

    • 初始化階段(初始化列表),也就是爲各個數據成員分配相應的空間;
    • 普通計算階段(函數體中的操作,如給數據成員賦值等)。
      由上可知,類數據成員初始化化完成之後纔會進入構造函數函數體中。
  3. 必須使用初始化列表的情況:

    • 任何const成員數據,因爲const變量一旦確定不能改變,則必須在初始化時確定,在普通計算階段(構造函數體內)進行賦值操作時不可以的;
    • 引用類型成員, 因爲引用是別名,則定義引用時必須初始化,在函數體中直接賦值時該引用必須是已經定義過得,所以引用也必須在初始化列表中;
    • 沒有默認構造函數的類類型的成員,如果沒有爲類成員提供初始化式,則編譯器將會調用。
  4. 數據成員在初始化次序與其聲明順序有關,與在初始化列表中的順序無關。

  5. 如果類包含內置或複合類型的成員,則該類應該定義自己的構造函數來初始化這些成員。

  6. 抑制構造函數的隱式轉化,使用explicit關鍵字
class A{
    A(string str);
    bool isSame(A&);
}
string str = "str";
A a = new A("aaa");
a.isSame(str);//會隱式的將string類型轉化爲A對象,進行判斷。但是這個往往會造成誤區,所以用explicit關鍵字來說明參數不接受隱式轉化, explicit bool isSame(A&)

5. 友員

  1. 爲了實現一個類使用另一個類的私有成員。

  2. 例子:

class A{
    friend class B;  //B可以用A中的私有成員和函數,但B不是A的數據成員
    friend int C::get();  // C的get方法可以用A中的私有成員和函數,但此函數不是A的成員函數
}
  • 必須先定義包含成員函數的類,才能將成員類或者函數定義爲友元。即必須定義A,才能定義B和C。因爲B和C中依賴A中定義的成員。
  • 但是它們的聲明沒有限制。

6. static類成員

  1. 與類有關,與類對象無關;
  2. 優點:

    • 在類作用域中,避免與其他變量名衝突;
    • 封裝,只與該類有關;
    • 可以用於存儲和類對象無關的成員,意圖明確。如Thread類中的sleep()函數。
  3. 沒有this指針

  4. const static成員,可以在類的定義體重初始化,但是仍需在類外進行定義。普通成員不行。
  5. static數據成員的類型可以是該成員所屬的類型,因爲static成員獨立於任何對象而存在,不是類類型對象的組成部分。(非static必須是指針或引用)
class A{
    static A a; //ok
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章