第七講 建構函式與析構函式

2021-07-22 13:25:34 字數 3834 閱讀 8027

第七講:建構函式與析構函式

* 掌握:構造和析構函式概念、初始化、作用。

* 理解:構造構函的過載; 帶引數的建構函式兩種表達格式。

重點、難點

* 構造和析構函式概念、初始化、作用。

通過前兩章的學習,我們已經對類和物件有了初步的了解。在本章中將對類和物件進行進一步的討論。在這一章中將會遇到一些稍為複雜的概念,請同學們多用心學,是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。分別求它們的體積。編寫乙個程式,在類中用帶引數的建構函式。

#include

using namespace std;

class box 

;//在類外定義帶引數的建構函式

box::box(int h,int w,int len)

int box::volume() //定義計算體積的函式

int main()

例如:例2中定義建構函式可以改用以下形式:

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 物件...