這篇部落格來介紹一下類的預設成員函式,在類中有6個預設成員函式,就算乙個類什麼都沒有,也會自動生成這6個預設成員函式。那麼這6個預設成員函式是什麼呢?
完成初始化和清理的兩個函式
建構函式和析構函式
完成拷貝複製的兩個函式
拷貝建構函式和賦值過載函式
取位址過載的兩個函式
普通物件和const物件取位址函式,這兩個函式一般不需要自己實現。
話不多說,進入正題。
建構函式是特殊的成員函式,需要注意的是,建構函式的雖然名稱叫構造,但是需要注意的是建構函式的主要任務並不是開空間建立物件,而是初始化物件。
函式名與類名相同。
無返回值。
物件例項化時編譯器自動呼叫對應的建構函式。
建構函式可以過載
為什麼會有建構函式的出現呢?
我們先用前面的知識寫乙個日期類
class
date
void
display()
private
:int _year;
int _month;
int _day;};
intmain()
在上面這個類中,可以看到我們首先定義了兩個日期類d1 d2,然後呼叫這個類中的函式,首先是初始化函式setdate,列印函式dispiay。這樣才會讓得到定義的兩個日期類得到實現。但是這樣有沒有什麼不好的地方呢?如果你忘了初始化直接列印訪問會怎麼樣呢?會得到隨機值。還有假設乙個場景,進行快排的非遞迴,運用棧的功能,但是一開始沒有初始化,所以會得到隨機的值,這樣子在陣列中訪問就會崩潰的。乙個程式設計師很有可能在寫程式中忘掉初始化這個東西。
所以能不能物件一定義出來就初始化了?這樣子set這個函式就可以不用了。
有,建構函式就可以完成這個功能,那麼這個建構函式應該怎樣實現?
往下看
class
date
// 2.帶參建構函式
date (
int year,
int month ,
int day )
private
:int _year ;
int _month ;
int _day ;};
void
testdate()
物件被定義出來直接初始化,這樣子是不是很簡單呢?上面是我們自己寫的建構函式,但是在前面我們也講了乙個空類也會有預設的成員函式。
如果類中沒有顯式定義建構函式,則c++編譯器會自動生成乙個無參的預設建構函式,一旦使用者顯式定義編譯器將不再生成。
class
date
*/private
:int _year;
int _month;
int _day;};
void
test()
無參的建構函式和全預設的建構函式都稱為預設建構函式,並且預設建構函式只能有乙個。注意:無參建構函式、全預設建構函式、我們沒寫編譯器預設生成的建構函式,都可以認為是預設成員函式。
public
:date()
date
(int year =
1900
,int month =1,
int day =1)
private
:int _year;
int _month;
int _day;};
// 以下測試函式能通過編譯嗎?
void
test()
答案是不行,因為在這個類中有多個預設建構函式,所以通過不了編譯。這兩個函式都不需要傳參,所以這兩個函式不能同時存在。不知道呼叫哪個,有歧義。雖然構成了函式過載。這裡可能會有小夥伴提出疑問了?上面不是有無參函式和帶參函式在一起都被定義實現的例子麼?是的,那兩個函式組合在一起可以實現,但是是如果乙個全預設函式和它們兩個任意搭配的話就不可以實現了。與帶參函式不可以一起實現的原因是它兩不構成函式過載。在我這裡建議使用全預設函式為預設建構函式。這樣作用域更廣一些,這樣子更好用一點。
關於編譯器生成的預設成員函式,很多童鞋會有疑惑:在我們不實現建構函式的情況下,編譯器會生成預設的建構函式。但是看起來預設建構函式又沒什麼用?d物件呼叫了編譯器生成的預設建構函式,但是d物件year/month/_day,依舊是隨機值。也就說在這裡編譯器生成的預設建構函式並沒有什麼卵
用??解答:c++把型別分成內建型別(基本型別)和自定義型別。內建型別就是語法已經定義好的型別:如
int/char…,自定義型別就是我們使用class/struct/union自己定義的型別,看看下面的程式,就會發現編譯器生成預設的建構函式會對自定型別成員_t呼叫的它的預設成員函式。
class
time
private
:int _hour;
int _minute;
int _second;};
class
date
;int
main()
我們不實現建構函式的時候,編譯器會生成乙個預設建構函式。基本型別不初始化,自定義型別,會呼叫它的預設建構函式進行初始化。
就像上面**中,日期類中巢狀了乙個time類,定義了乙個自定義型別的類,在這裡也會完成自己的初始化,雖然沒有寫出來,但是就是呼叫了編譯器預設生成的預設建構函式。
以上就是建構函式的一些小知識。接下來進入析構函式。
前面通過建構函式的學習,我們知道乙個物件時怎麼來的,那乙個物件又是怎麼沒呢的?
析構函式:與建構函式功能相反,析構函式不是完成物件的銷毀,區域性物件銷毀工作是由編譯器完成的。而物件在銷毀時會自動呼叫析構函式,完成類的一些資源清理工作。
特性析構函式是特殊的成員函式。
其特徵如下:
析構函式名是在類名前加上字元 ~。
無引數無返回值。乙個類有且只有乙個析構函式。若未顯式定義,系統會自動生成預設的析構函式。
物件生命週期結束時,c++編譯系統系統自動呼叫析構函式
typedef
int datatype;
class
seqlist
~seqlist()
}private
:int
* _pdata ;
size_t _size;
size_t _capacity;
};
關於編譯器自動生成的析構函式,是否會完成一些事情呢?下面的程式我們會看到,編譯器生成的預設析構函式,對會自定型別成員呼叫它的析構函式
class
string
~string()
private
:char
* _str;};
class
person
;int
main()
c 類和物件 2
1 設計類就是設計型別 1 我們給這個賦予什麼合法值。2 類中包含什麼樣的函式和操作符。3 新型別的物件該如何被建立和銷毀。4 物件的初始化和賦值。5 物件作為函式的引數如何以值傳遞。6 誰使用此型別的物件成員。private 私有成員,只允許本類中的函式訪問,而類外部的任何函式都不能訪問。如果緊跟...
C 類和物件(2)
如果乙個類中什麼成員都沒有,就稱該類為空類,但是空類中並不是什麼都沒有,任何乙個類在我們不寫的情況下,都會自動生成6個預設成員函式。class student 建構函式雖然叫做構造,但是並不是構造物件,而是完成初始化工作。class date void print private int year ...
C 初識 類和物件(2)
在之前的文章裡,我們出初步了解了,什麼是類,類如何定義,類的大小怎麼計算等 乙個空類裡面什麼也沒有,但是它並非是什麼也沒有,只要是類,它就有6個預設的成員函式 1.建構函式 2.析構函式 3.拷貝建構函式 4.賦值操作符過載 5.取位址操作符過載 6.const修飾的取位址操作符過載 類的建構函式 ...