今天我們了解一下類的建構函式、析構函式。其中建構函式會提到預設建構函式、過載建構函式和複製建構函式。好了,現在開始我們的旅程吧。
首先溫習一下c和c++中分配記憶體的方法。我們知道,c中的malloc/free和c++中的new/delete是用來分配記憶體和釋放記憶體的,這裡的記憶體是前面博文提到的「堆」。(如果不了解什麼是堆,請參考文章《c\c++的記憶體儲存》 )他們的區別如下:
new=malloc+建構函式;//分配記憶體和呼叫建構函式,這是new的主要作用
delete=析構函式+free;//呼叫析構函式,釋放記憶體,這是delete的主要作用
好了,現在進入正題。提到建構函式和析構函式,我們的了解一下他們的概念。建構函式是在建立類物件的時候使用給定的值來將物件初始化;析構函式的功能是釋放乙個物件,在物件被刪除之前做一些物件清理工作。需要說明的是,建構函式和析構函式都沒有返回值。建構函式可以帶引數,可以過載;析構函式沒有引數,不能過載。表1是建構函式與析構函式特點的對比。
表1 建構函式與析構函式特點的對比
建構函式
析構函式
名字與類名相同
名字與類名相同,並在前面加乙個~字元
可以過載,乙個類中可以有多個建構函式
乙個類中只能有乙個析構函式
程式中不能直接呼叫建構函式
析構函式可以直接在程式中被呼叫
例項化物件時最先被呼叫的函式
類物件在析構時最後乙個被呼叫的函式
了解了建構函式和析構函式的基本特點後,我們先著重學習建構函式的相關知識。
1 預設建構函式
預設建構函式是指不需要指定實參就能被呼叫的建構函式。需要注意的問題有一下幾點:
1)乙個類中不能有多個預設建構函式,這會導致在使用這個類去例項化類物件的時候編譯出錯,因為編譯器不知道要呼叫哪乙個預設建構函式去例項化類物件。
2)乙個類中可以沒有預設建構函式的定義。因為編譯的時候,編譯器會自動產生乙個預設建構函式,以便這個類在變異階段能通過編譯。但是,最好不要使用編譯器提供的預設建構函式,因為你永遠不知道編譯器提供的預設建構函式會做些什麼,這可能導致不可預知的問題,所以還是自己定義預設建構函式吧,哪怕是乙個空的預設建構函式。
2 過載建構函式
帶引數的建構函式也就是建構函式的過載。通過形參列表初始化類中的資料成員。需要強調的是,如果過載了建構函式,那麼必須自定義預設建構函式,否則編譯器會提示錯誤:
intellisense: no default constructor exists for class "***"
可以有多個過載建構函式,但是這些函式的形參列表必須不同,以達到編譯時編譯器能夠識別被呼叫的是哪個建構函式。
3 複製建構函式
複製建構函式的功能是用乙個已知物件來初始化另乙個同類的物件。複製建構函式其實也是類的建構函式,只不過被呼叫的時候,會自動將乙個已知物件的資料成員的值拷貝給另乙個同類物件。複製建構函式的特點如下:
複製建構函式名稱與類名相同;
複製建構函式必須有且只有乙個引數,是該類物件的引用;
每個類必須有乙個複製建構函式。如果定義類的時候自己沒有寫,編譯器編譯時會自動生成乙個複製建構函式;
複製建構函式格式:《類名》::《類名》(const《類名》&《引用名》)
下面給乙個簡單的類定義。
1: #include
2: usingnamespace std;
3:
4: class test
5: ;
14:
15: int main()
16:
22:
23:程式的執行結果如下圖所示。
現在我們嘗試把test(int valuea)注釋掉,看看會有什麼結果。不出意外,得到的答案是
這就是我在前面提到需要注意的問題:如果過載了建構函式,那麼必須自定義預設建構函式。
感謝:《c++程式設計關鍵路徑——程式設計師求職指南》
C 之類建構函式與析構函式
類的建構函式是類的一種特殊的成員函式,它會在每次建立類的新物件時執行。建構函式的名稱與類的名稱是完全相同的,並且不會返回任何型別,也不會返回 void。建構函式可用於為某些成員變數設定初始值。class aa a void 使用初始化列表來初始化字段 line line double len len...
c 構造與析構
c 中還提供了一些封裝方法 構造方法 析構方法 一 在宣告乙個類的物件後,要對該物件進行初始化,即對物件中的資料成員賦值 建構函式 用於建立乙個物件,提供初始化該物件的簡單手段 函式語法 建構函式的函式名必須與類名相同 它沒有返回值 作用為初始化物件 其呼叫是在宣告物件時候自動呼叫 python中的...
C 繼承與構造析構
include 子類物件可以當作父類物件使用 子類物件可以直接賦值給父類物件 子類物件可以直接初始化父類物件 父類指標可以直接指向子類物件 父類引用可以直接引用子類物件 子類物件構造時,需要呼叫父類建構函式對其繼承得來的成員進行初始化 子類物件析構時,需要呼叫父類析構函式對其繼承得來的成員進行清理 ...