C 物件導向 類和物件的使用(一)

2021-09-05 15:52:23 字數 4331 閱讀 1587

這部分算是正式接觸了類和物件,涉及到它們基礎的應用。

目錄

建構函式對類物件進行初始化

1、物件的初始化

2、建構函式實現資料成員的初始化

3、帶引數的建構函式

4、引數初始化表對資料成員的初始化

5、建構函式的過載

6、使用預設引數的建構函式

析構函式

建構函式與析構函式

物件陣列

當物件在建立時獲得了乙個特定的值,我們說這個物件被初始化。初始化不是賦值,初始化的含義是建立變數賦予其乙個初始值,而賦值的含義是把當前值擦除,而以乙個新值來替代。在組合語言中,為變數分配空間時,初始化過的變數的初值位於可執行檔案**段資料後,會占用一定空間,不必要的初始化會造成磁碟空間的浪費。而在c/c++語言等高階語言中,為每乙個變數賦初值被視為良好的程式設計習慣,有助於減少出現bug的可能性。因此,是否對不必要的變數初始化依情況而定。初始化時是按照資料成員在類裡被宣告的順序進行初始化

物件的初始化和之前的那些定義變數時的初始化不一樣,它不能在類宣告中對資料進行初始化,因為類並不是乙個實體,而是一種抽象型別,不占用儲存空間,無法容納資料。

class time;
如果乙個類中所有的資料成員都是公用的,那麼在定義物件時可以對資料成員進行初始化。但一般來說類中的資料成員都是私有的,因為要保持資訊隱蔽的特性,所以這種方法基本上不會有。

class time;

time t= ; //此處注意是中括號,和後邊建構函式初始化的表示不一樣。

建構函式是一種特殊的成員函式,與其它成員函式不同,不需要使用者呼叫,也不能被使用者呼叫,而是在建立物件時自動執行。建構函式的名字必須是與類名一樣,不能任意命名,以便系統能識別它作為建構函式處理。且不具有任何型別,不返回任何值,只是對物件進行初始化

class time

};

在主函式執行時,一旦類建立物件,該建構函式將會自動執行,執行建構函式的過程中對 物件 中的資料成員賦初值,賦值在建構函式體中實現。另外還可以在類內僅宣告建構函式,在類外對建構函式進行定義,只需加上  類名 和域限定符 「::」 即可。

class time; 

time :: time()

當類建立物件時,系統開始為這個物件分配儲存單元,此時便執行建構函式,每建立乙個物件,就呼叫乙個建構函式。建構函式是定義物件時由系統自動執行的,而且只能執行一次,建構函式一般宣告為 public。另外還可以用乙個類物件對另乙個類物件進行初始化。

time t1 ;

time t2=t1 ;

在建構函式的函式體中可以有其他語句,像 「cout···」等語句,但一般不提倡在建構函式中加入與初始化無關的內容,以保持程式的清晰。如果使用者自己沒有定義建構函式,系統會自動生成乙個建構函式,只是這個建構函式體是空的,也沒有任何引數,不執行任何初始化操作。

在呼叫不同物件的建構函式時,從外面將不同的資料傳遞給建構函式,以實現不同的初始化,即在建立物件時同時指定資料成員的初值。如下:

class time

}; int main()

這種初始化物件的方法使用起來很方便,也很直觀,從定義的語句中就能直接看到資料成員的初值。

引數的初始化表法算是帶引數的建構函式的一種,不過減少了函式體的長度,使結構體顯得精煉簡單,可以直接在類體中定義建構函式,尤其當需要初始化的資料成員較多時更具有優越性。

class time

//time(int h=0,int m=0,int s=0):hour(h),min(m),sec(s){}

}; int main()

一般引數初始化表中的中括號內是空的,不執行任何語句。

在乙個類中可以定義多個建構函式,這些建構函式具有相同的名字,引數的個數或引數的型別不相同,以便為物件提供不同的初始化的方法。

class time

time(int h,int m,int s):hour(h),min(m),sec(s){} //有引數的建構函式,並用初始化表進行初始化。

}; int main()

在建立物件時不必給出實參的建構函式稱為預設建構函式,顯然無引數建構函式屬於預設建構函式。乙個類中只能有乙個預設建構函式,否則的話系統將不知道去呼叫哪個建構函式進行初始化。另如果使用者未定義建構函式,則系統會1自動提供乙個預設建構函式,但它的函式體是空的,不起初始化作用。如果使用者希望在建立物件時就能使資料成員有初值,就必須自己定義建構函式。雖然在乙個類中有多個建構函式,但對於乙個物件來說,建立乙個物件時只呼叫其中乙個建構函式,並非每個建構函式都被執行。另外在建立物件時如果選用的是無參建構函式,注意正確的書寫定義物件的語句:

time t1;

time t2(); //錯誤

在宣告建構函式時指定預設值而不是在定義建構函式時給出其預設值,宣告建構函式時,形參名可以省略。

time (int =0 ,int =0,int =0);
在建立物件時不必給出實參,但乙個類中只能有乙個預設建構函式,為了避免呼叫時的歧義性,另外如果在乙個類中定義了全部是預設引數的建構函式後,不能再定義過載建構函式,即此時類中只能存在乙個預設引數的建構函式。

class time	//有引數的建構函式,並用初始化表進行初始化。 

time()

time(int h,int m)

}; int main()

另外如果建構函式中的引數並非全部為預設值時,要根據1具體情況而定。

time();

time(int , int m=0, int s=0);

time(int , int)

time t1; //呼叫第乙個,無參建構函式

time t2(1); //呼叫第二個,實參與形參從左到右一一對應

time t3(1,1); //出現歧義

所以我們一般不同時使用建構函式的過載和有預設引數的建構函式,出現二義性的可能性大。

析構函式的功能與建構函式的功能相反,它的名字是 類名的前面加乙個「~」符號,「~」 在這裡是表示位取反運算子 ,可以想到析構函式是與建構函式作用相反的函式。

物件的生命週期結束時,也是自動執行析構函式。有以下幾種情況:

如果在乙個函式中定義了乙個物件(區域性物件),當這個函式被呼叫結束時,物件應該釋放,在物件釋放前自動執行析構函式。

靜態(static)區域性物件在函式呼叫結束時物件並不釋放,因此也不用呼叫析構函式,只有在 main 函式結束或者呼叫 exit 函式結束程式時,才呼叫 static 區域性物件的析構函式。

如果定義了乙個全域性的物件,則在程式的流程離開其作用域時(如 main 函式結束或呼叫 exit 函式),呼叫該全域性的物件的析構函式。

如果用new運算子動態地建立了乙個物件 ,當用 delete 運算子釋放該物件時,先呼叫該物件的析構函式。

析構函式的作用並不是刪除物件,而是撤銷物件占用的記憶體之前完成一些清理工作,使這部分記憶體可以被程式分配給新物件使用(比如你在構造或者做某個程式的時候,開闢了記憶體空間(如陣列),如果沒有在析構之前釋放它,則記憶體不會自動釋放,會造成記憶體洩露)。程式設計者要事先設計好析構函式,以完成所需的功能,主要物件的生命週期結束,程式就自動執行析構函式來完成這些工作。

析構函式不返回任何值,沒有函式型別,也沒有函式引數,故它不能被過載。乙個類可以有多個建構函式,但只能有乙個析構函式。析構函式的作用並不僅限於釋放資源方面,它還可以被用來執行 「使用者希望在最後一次使用物件之後所執行的任何操作」,如輸出有關的資訊。

一般情況下,類的設計者應當在宣告類的同時定義析構函式,以指定如何完成 「清理」 的工作。如果使用者沒有定義析構函式,系統也會自動生成乙個析構函式,但它只是徒有析構函式的名稱和形式,實際上什麼操作都不執行。想讓析構函式完成任何工作,都必須在定義的析構函式中指定。

class time

void show()

void show()

void show(){

cout<

C 物件導向 類和物件的使用(二)

目錄 物件指標 1 指向物件的指標 2 指向物件成員的指標 3 指向當前物件的 this 指標 共用資料的保護 1 常物件 2 常物件成員 3 指向物件的常指標 4 指向常物件的指標 5 物件的常引用 6 const 型資料小結 指標不僅可以指向普通變數,也可以指向物件。乙個物件儲存空間的起始位址就...

c 物件導向 類和物件

define crt secure no warnings include include using namespace std struct hero void printhero struct hero h class advhero class animal 以內 叫類的內部,以外叫類的外部...

物件導向 物件和類

類和物件使物件導向程式設計技術中的最基本概念。是現實或思維世界中的實體在計算中的反映,它將資料以及這些資料上的操作封裝在一起。類是抽象的,是建立例項物件的模板 是具有類型別的變數 是乙個乙個具體的例項 物件中包含類的屬性和方法 類和物件的區別就是 魚和三文魚 貓和藍貓的區別。class 類名稱 cl...