C/C++複習

AjdeDjokovic發表於2020-10-22

建構函式

  1. 在C++中,有一種特殊的成員函式,它的名字和類名相同,沒有返回值,不需要使用者顯式呼叫(使用者也不能呼叫),而是在建立物件時自動執行。這種特殊的成員函式就是建構函式(Constructor)。
  2. 建構函式的呼叫是強制性的,一旦在類中定義了建構函式,那麼建立物件時就一定要呼叫,不呼叫是錯誤的。如果有多個過載的建構函式,那麼建立物件時提供的實參必須和其中的一個建構函式匹配;反過來說,建立物件時只有一個建構函式會被呼叫。

預設建構函式

  1. 如果使用者自己沒有定義建構函式,那麼編譯器會自動生成一個預設的建構函式,只是這個建構函式的函式體是空的,也沒有形參,也不執行任何操作。
  2. 一個類必須有建構函式,要麼使用者自己定義,要麼編譯器自動生成。一旦使用者自己定義了建構函式,不管有幾個,也不管形參如何,編譯器都不再自動生成。
  3. 最後需要注意的一點是,呼叫沒有引數的建構函式也可以省略括號。對於示例2的程式碼,在棧上建立物件可以寫作Student stu()或Student stu,在堆上建立物件可以寫作Student *pstu = new Student()或Student *pstu = new Student,它們都會呼叫建構函式 Student()。

建構函式初始化列表

  1. 成員變數的初始化順序與初始化列表中列出的變數的順序無關,它只與成員變數在類中宣告的順序有關。
  2. 使用初始化列表少了一次呼叫預設建構函式的過程
  3. 必須使用初始化列表的情況
  1. 常量成員,因為常量只能初始化不能賦值,所以必須放在初始化列表裡面
  2. 引用型別,引用必須在定義的時候初始化,並且不能重新賦值,所以也要寫在初始化列表裡面
  3. 沒有預設建構函式的類型別,因為使用初始化列表可以不必呼叫預設建構函式來初始化,而是直接呼叫拷貝建構函式初始化
  1. 從概念上來講,建構函式的執行可以分成兩個階段,初始化階段和計算階段,初始化階段先於計算階段.
  1. 初始化階段
    所有類型別(class type)的成員都會在初始化階段初始化,即使該成員沒有出現在建構函式的初始化列表中.
  2. 計算階段
    一般用於執行建構函式體內的賦值操作。

new & delete

  • C++ 中的 new 和 delete 分別用來分配和釋放記憶體,它們與C語言中 malloc()、free() 最大的一個不同之處在於:用 new 分配記憶體時會呼叫建構函式,用 delete 釋放記憶體時會呼叫解構函式。

this

  1. this 實際上是成員函式的一個形參,在呼叫成員函式時將物件的地址作為實參傳遞給 this。不過 this 這個形參是隱式的,它並不出現在程式碼中,而是在編譯階段由編譯器默默地將它新增到引數列表中。
  2. this 作為隱式形參,本質上是成員函式的區域性變數,所以只能用在成員函式的內部,並且只有在通過物件呼叫成員函式時才給 this 賦值。
  3. 成員函式最終被編譯成與物件無關的普通函式,除了成員變數,會丟失所有資訊,所以編譯時要在成員函式中新增一個額外的引數,把當前物件的首地址傳入,以此來關聯成員函式和成員變數。這個額外的引數,實際上就是 this,它是成員函式和成員變數關聯的橋樑。
    轉載 C++函式編譯原理和成員函式的實現

生命週期和有效範圍

  1. 在函式內定義的變數是區域性變數,而在函式之外定義的變數則稱為外部變數,外部變數也就是我們所講的全域性變數。它的儲存方式為靜態儲存,其生存週期為整個程式的生存週期。全域性變數可以為本檔案中的其他函式所共用,它的有效範圍為從定義變數的位置開始到本原始檔結束。
  2. 然而,如果全域性變數不在檔案的開頭定義,有效的作用範圍將只限於其定義處到檔案結束。如果在定義點之前的函式想引用該全域性變數,則應該在引用之前用關鍵字 extern 對該變數作“外部變數宣告”,表示該變數是一個已經定義的外部變數。有了此宣告,就可以從“宣告”處起,合法地使用該外部變數。
    轉載 extern關鍵字,C語言extern關鍵字用法詳解

連結

  • 在程式執行之前確定符號地址的過程叫做靜態連結(Static Linking);如果需要等到程式執行期間再確定符號地址,就叫做動態連結(Dynamic Linking)。

C++新增行內函數

  • 要在函式定義處新增 inline 關鍵字