1.建構函式
建構函式是乙個特殊的成員函式,名字與類名相同,建立類型別物件時,由編譯器自動呼叫,在物件的生命週期內隻且值呼叫一次,以保證每個資料成員都有乙個合適的初始值。
【建構函式特性】
1、函式名與類名相同。
2、沒有返回值。
3、有初始化列表(可以不用)。
4、新物件被建立,由編譯器自動呼叫,且在物件的生命期內僅呼叫一次。
5、建構函式可以過載,實參決定了呼叫那個建構函式。
6、如果沒有顯示定義時,編譯器會提供乙個預設的建構函式。
如果乙個類中沒有定義任何的建構函式,那麼編譯器只有在以下三種情況,才會提供預設的建構函式:
1、如果類有虛擬成員函式或者虛擬繼承父類(即有虛擬基類)時;
2、如果類的基類有建構函式(可以是使用者定義的建構函式,或編譯器提供的預設建構函式);
3、在類中的所有非靜態的物件資料成員,它們對應的類中有建構函式(可以是使用者定義的建構函式,或編譯器提供的預設建構函式)
7、無參建構函式和帶有預設值得建構函式都認為是預設建構函式,並且預設建構函式只能有乙個。
因為在呼叫是如果出現date( ),編譯器並不知道該呼叫哪乙個建構函式;
date( int year = 1990, int month = 1, int day = 1)
//date( )
8、建構函式不能用const來修飾,為什麼呢?
【初始化列表】
初始化列表:以乙個冒號開始,接著是乙個以逗號分隔的資料成員列表,每個資料
成員後面跟乙個放在園括號中的初始化式。
date(int
year = 1990, int
month = 1, int
day = 1)
:_year(year)
, _month( month)
, _day( day)
常量,變數的引用,和沒有預設初始化的類必須在初始化列表中初始化;
【初始化順序】
1、每個成員在初始化列表中只能出現一次。(為什麼?)
2、初始化列表僅用於初始化資料成員,並不指定這些資料成員的初始化順序,
資料成員在類中定義順序就是在引數列表中的初始化順序。
3、盡量避免使用成員初始化成員,成員的初始化順序最好和成員的定義順序保持一致。
【預設建構函式】
類如果沒有顯式定義建構函式時,編譯器會合成乙個預設的建構函式,該建構函式中什麼工作都不做。只要顯式定義了,即使該建構函式什麼也不做,編譯器也不會為該類合成預設的建構函式。編譯器生成的預設建構函式使用與變數初始化相同的規則來初始化成員,具有類型別的成員通過執行各自的預設建構函式來進行初始化。內建和符合型別的成員如指標、陣列,只對定義在全域性作用域中的物件初始化,當物件定義在區域性作用域時,內建和符合型別的成員不進行初始化。在某些情況下,預設建構函式是由編譯器隱式使用的。
建構函式作用:
1、構建物件
2、初始化物件
3、型別轉換
【explcit】
用explicit修飾建構函式,抑制由建構函式定義的隱式轉換,erplicit關鍵字類內部的構建宣告上,在類的定義體外部的定義上不再重複。
例:date類的建構函式:
class date
private:
int _year;
int _month;
int _day;
}
2.拷貝建構函式
只有單個形參,而且該形參是對本類型別物件的引用(常用const修飾),這樣的建構函式稱為拷貝建構函式。拷貝建構函式是特殊的建構函式,建立物件時使用已存在的同類物件來進行初始化,由編譯器自動呼叫。
date(const date & d)
【特徵】
1、它是建構函式的過載。
2、它的引數必須使用同型別物件的引用傳遞。(思考為什麼?)
3、如果沒有顯式定義,系統會自動合成乙個預設的拷貝建構函式。預設的拷貝建構函式會依次拷貝類的資料成員完成初始化。
【使用場景】
1、物件例項化物件
date d1(1990, 1, 1);
date d2(d1);
2、傳值方式作為函式的引數
void funtest(const date date)
{}3、傳值方式作為函式返回值
date funtest()
3.析構函式
析構函式:與建構函式功能相反,在物件被銷毀時,由編譯器自動呼叫,完成類的一些資源清理和汕尾工作;
【特性】
a、析構函式在類名(即建構函式名)加上字元~。
b、析構函式無引數無返回值。
c、乙個類有且只有乙個析構函式。若未顯示定義,系統會自動生成預設的析構函式。
d、物件生命週期結束時,c++編譯系統系統自動呼叫析構函式。
e、注意析構函式體內並不是刪除物件,而是做一些清理工作。
f、 認識到析構函式體本身並不直接銷毀成員是非常重要的。成員是在析構函式體之後隱含的析構階段中被銷毀的。
【什麼時候會呼叫析構函式】
無論何時,乙個物件被銷毀,就會自動呼叫其析構函式:
a.變數離開其作用域是被銷毀;
b.當乙個物件的銷毀時,其成員被銷毀;
c.容器(無論是標準庫容器還是陣列)被銷毀時,其元素被銷毀;
d.對於動態分配的物件,當指向它的指標用delete運算子被銷毀;
e.對於臨時物件,當建立它的完整表示式結束時被銷毀。
【 warning】
當指向乙個物件的引用或指標離開作用域時,析構函式不會執行。
4.賦值操作符過載;
5.取位址操作符過載;
6.const修飾的取位址操作符過載;
【操作符過載】
過載操作符是具有特殊函式名的函式,關鍵字operator後面接需要定義的操作符符號。
操作符過載也是乙個函式,具有返回值和形參表。它的形引數目與操作符的運算元目相同,
函式呼叫操作符可以接受任意數目的運算元。
返回型別 operate 操作符(引數列表);
注意:
1、不能通過連線其他符號來建立新的操作符:比如operator@;
void operator @(){}
2、過載操作符必須有乙個類型別或者列舉型別的運算元
int operator +(const int _inum1 , const int _inum2 ) // 報錯
typedef enum test ;
int operator+(const int _inum1 , const test _test )
3、用於內建型別的操作符,其含義不能改變,例如:內建的整型+,不能改變其含義
5、不在具備短求職特性
過載操作符不能保證操作符的求職順序,在過載&&和||中,對每個運算元
都要進行求值,而且對運算元的求職順序不能做規定,因此:過載&&、
||和逗號操作符不是好的做法。
6、作為類成員的過載函式,其形參看起來比運算元數目少1
成員函式的操作符有乙個預設的形參this,限定為第乙個形參。
ctest operator+(const ctest test1, const ctest test2)const // 報錯
ctest operator+(const ctest test1)const
7、一般將算術操作符定義為非成員函式,將賦值運算子定義成員函式
8、操作符定義為非類的成員函式時,一般將其定義為類的友元函式
9、== 和 != 操作符一般要成對過載
10、下標操作符:乙個非const成員並返回引用,乙個是const成員並返回引用
11、解引用操作符*和->操作符,不顯示任何引數
13、自增自減操作符
前置式++/–必須返回被增量或者減量的引用
字尾式操作符必須返回舊值,並且應該是值返回而不是引用返回
14、輸入操作符》和輸出操作符《必須定義為類的友元函式
【建議】
使用過載操作符,可以令程式更自然、更直觀,而濫用操作符過載會使得類難以理解,在實踐中很少發生明顯的操作符過載濫用。但有些程式設計師會定義operator+來執行減法操作,當乙個過載操作符不明確時,給操作符取乙個名字更好,對於很少用的操作,使用命名函式通常比用操作符好,如果不是普通操作,沒有必要為簡潔而用操作符。
賦值操作符過載;(以date類為例)
date& operator=(const date& d)//定義為類的成員函式
取位址操作符過載和const修飾的取位址操作符過載; ;
class ctest
const ctest* operator &()const
C 中類的6個預設成員函式
注意 注意 注意 注意 簡單歸納 函式返回值 引數作用 建構函式 無返回值 有參和無參兩種 初始化物件 析構函式 無返回值 無引數物件生命週期結束時,在物件刪除前做清理工作 拷貝建構函式 無返回值 引用型別的引數 用已存在的物件建立新的對像 運算子過載 不定至少有乙個 方便c 中的操作 還有兩個預設...
C 類中的6個預設成員函式
引言 類的6個預設的成員函式包括 建構函式 析構函式 拷貝建構函式 賦值運算子過載函式 取位址操作符過載 const修飾的取位址操作符過載。這裡預設的意思是如果你不定義,則編譯器會自動生成,而在實際操作中,我們往往自己實現前四個,後兩個讓編譯器自動生成建構函式,顧名思義,為物件分配空間,進行初始化。...
C 類的6個預設成員函式
1.概念 名字與類名相同,建立類型別物件時由編譯器自動呼叫,保證每個資料成員都有乙個合適的初 始值,並且在物件的生命週期內只呼叫一次。2.特性 雖然名字叫構造,但其主任務並不是開闢空間建立物件,而是初始化物件。函式名與類名相同,無返回值,物件例項化時編譯器自動呼叫對應的建構函式,建構函式可以過載,通...