第七講:建構函式與析構函式
* 掌握:構造和析構函式概念、初始化、作用。通過前兩章的學習,我們已經對類和物件有了初步的了解。在本章中將對類和物件進行進一步的討論。在這一章中將會遇到一些稍為複雜的概念,請同學們多用心學,是c++的基礎,也是面象物件程式設計的基礎。* 理解:構造構函的過載; 帶引數的建構函式兩種表達格式。
重點、難點
* 構造和析構函式概念、初始化、作用。
一、建構函式
1、物件的初始化
物件的初始化和結構體變數的初始化是差不多的,在乙個花括號內順序列出各公用資料成員的值,兩個值之間用逗號分隔。如:
class time
;time t1=;//將tl初始化為14:56:30
說明:1、如果資料成員是私有的,或者類中有private或protected的成員,就不能用這種方法初始化。
在建立乙個物件時,常常需要作某些初始化的工作。
2、類的資料成員是不能在宣告類時初始化的。下面的寫法是錯誤的:
class time
; 因為類並不是乙個實體,而是一種抽象型別,並不佔儲存空間,顯然無處容納資料。如果乙個類中所有的成員都是公用的,則可以在定義物件時對資料成員進行初始化。
3、用成員函式來對物件中的資料成員賦初值的(例如上章中3中的set_time函式)。從例3中可以看到,使用者在主函式中呼叫set_time函式來為資料成員賦值。如果對乙個類定義了多個物件,而且類中的資料成員比較多,那麼,程式就顯得非常臃腫煩瑣,這樣的程式**還有質量和效率?
2、建構函式的作用
建構函式的作用:面象物件的程式設計提供了建構函式(constructor)來處理物件的初始化。建構函式是一種特殊的成員函式,與其他成員函式不同,不需要使用者來呼叫它,而是在建立物件時自動執行。建構函式的名字必須與類名同名,而不能由使用者任意命名,以便編譯系統能識別它並把它作為建構函式處理。它不具有任何型別,不返回任何值。建構函式的功能是由使用者定義的,使用者根據初始化的要求設計函式體和函式引數。
無引數建構函式格式:
類名( )
例1 在例2.3的基礎上定義構造成員函式。
#include
using namespace std;
class time
void set_time(); //函式宣告
void show_time(); //函式宣告
private:
//私有資料成員
int hour;
int minute;
int sec;};
void time::set_time() //定義成員函式,向資料成員賦值
void time::show_time() //定義成員函式,輸出資料成員的值
程式執行的情況為:建構函式的使用說明:10 25 54/ (從鍵盤輸入新值賦給t1的資料成員)
l0:25:54 (輸出t1的時、分、秒值)
0:0:0 (輸出t2的時、分、秒值)
(1)在類物件進入其作用域時呼叫建構函式,建構函式一般宣告為 public。
(2)建構函式沒有返回值,因此也不需要在定義建構函式時宣告型別,建構函式的作用主要是用來對物件進行初始化。
(3)建構函式不需使用者呼叫,也不能被使用者呼叫。
(4)在建構函式的函式體中不僅可以對資料成員賦初值,而且可以包含其他語句。但是一般不提倡在建構函式中加入與初始化無關的內容,以保持程式的清晰。
(5)如果使用者自己沒有定義建構函式,則系統會自動生成乙個建構函式,只是這個建構函式的函式體是空的,也沒有引數,不執行初始化操作。
3、帶引數的建構函式
帶引數的建構函式定義格式為:
建構函式名(型別1形參1,型別2形參2,…)
呼叫帶引數的建構函式在定義物件一般格式為:
類名物件名(實參1,實參2,…);
例2 有兩個長方柱,其長、寬、高分別為:(1)12,25,30;(2)15,30,2l。分別求它們的體積。編寫乙個程式,在類中用帶引數的建構函式。例如:例2中定義建構函式可以改用以下形式:#include
using namespace std;
class box
;//在類外定義帶引數的建構函式
box::box(int h,int w,int len)
int box::volume() //定義計算體積的函式
int main()
box::box(int h,int w,int len):height(h),width(w),length(len)
5、建構函式的過載
在乙個類中可以定義多個建構函式,以便對類物件提供不同的初始化的方法,供使用者選用。這些建構函式具有相同的名字,而引數的個數或引數的型別不相同。這稱為建構函式的過載。
例3 在例2的基礎上,定義兩個建構函式,其中乙個無引數,乙個有引數。三、呼叫建構函式和析構函式的順序#include
using namespace std;
class box
//宣告乙個有參的建構函式,用引數的初始化表對資料成員初始化
int volume();
private:
int height;
int width;
int length; };
box::box() //定義乙個無參的建構函式
int box::volume()
int main()
;box::box(int w,int h,int len) //在定義函式叫可以不再指定引數的預設值
int box::volume()
int main()
~student() //定義析構函式
程式執行結果如下:
constructor called.
(執行studl的建構函式)
num:loolo
(執行studl的display函式)
name:wang_li
***:f
constructor called.
(執行stud2的建構函式)
num:10011
(執行stud2的display函式)
name:zhang_fun
***:m
destructor called.
(執行stud2的析構函式)
destructor called.
(執行smdl的析構函式)
在使用建構函式和析構函式時,需要特別注意對它們的呼叫時間和呼叫順序。
其對應的析構函式最先被呼叫。如圖所示。可簡記為:先構造的後析構,後構造的先析構。它相當於乙個棧,先進後出。
下面歸納一下什麼時候呼叫建構函式和析構函式:
(1)在全域性範圍中定義的物件(即在所有函式之外定義的物件),它的建構函式在檔案中的所有函式(包括main函式)執行之前呼叫。但如果乙個程式中有多個檔案,而不同的檔案中都定義了全域性物件,則這些物件的建構函式的執行順序是不確定的。當main函式執行完畢或呼叫exit函式時(此時程式終止),呼叫析構函式。
(2)如果定義的是區域性自動物件(例如在函式中定義物件),則在建立物件時呼叫其建構函式。如果函式被多次呼叫,則在每次建立物件時都要呼叫建構函式。在函式呼叫結束、物件釋放時先呼叫析構函式。
(3)如果在函式中定義靜態(static)區域性物件,則只在程式第一次呼叫此函式建立物件時呼叫建構函式一次,在呼叫結束時物件並不釋放,因此也不呼叫析構函式,只在main函式結束或呼叫exit.函式結束程式時,才呼叫析構函式。
建構函式與析構函式
建構函式 主要作用就是為物件初始化。有一點要說的是,在繼承體系彙總,如果在建構函式中,如果沒有指定基類的建構函式,那麼編譯器會在建構函式開頭加入,基類的預設建構函式,這樣就可以初始化基類物件部分 析構函式 對於析構函式,要說的多點,實際也不太複雜,就是加入了virtual 使其具有了多型性質 inc...
建構函式與析構函式
建構函式 先看看建構函式的呼叫順序規則,只要我們在平時程式設計的時候遵守這種約定,任何關於建構函式的呼叫問題都能解決 建構函式的呼叫順序總是如下 1.基類建構函式。如果有多個基類,則建構函式的呼叫順序是某類在類派生表中出現的順序,而不是它們在成員初始化表中的順序。2.成員類物件建構函式。如果有多個成...
建構函式與析構函式
概述 乙個類有兩種特殊的成員函式 建構函式與析構函式。建構函式功能是在建立物件時,給資料成員賦初值,即物件的初始化。析構函式的功能是釋放乙個物件,在物件刪除前,用它做一些記憶體釋放工作,與建構函式的功能相反。建構函式 在物件建立時它會被自動執行,因此變數 物件的初始化 一般都放在建構函式中。1 物件...