以前覺得吧,寫文章純屬浪費時間,有那麼點時間還不如玩會游戲、和姑娘聊聊天。現在這覺得,寫寫讀書筆記也是好的,一來信息分享,(各個雲平臺不就是分享、然後大數據麽)二來溫故而知新,加深了對知識的理解。話不多說,繼續寫 問題:在C++中一個空類,他會產生多少個函數呢? 答案還是慢慢揭曉,首先介紹C++幾....
以前覺得吧,寫文章純屬浪費時間,有那麼點時間還不如玩會游戲、和姑娘聊聊天。現在這覺得,寫寫讀書筆記也是好的,一來信息分享,(各個雲平臺不就是分享、然後大數據麽)二來溫故而知新,加深了對知識的理解。話不多說,繼續寫
問題:在C++中一個空類,他會產生多少個函數呢?
答案還是慢慢揭曉,首先介紹C++幾個成員函數。
構造函數:
什麼是構造函數?構造函數的作用又是什麼?可以有多少個構造函數?
首先,構造函數是類中一種特殊的成員函數,它和類是同名的、沒有返回值。構造函數的作用是什麼?我個人覺得他主要是用來提供類的各種初始化。
剛剛我講到了各種初始化,想必大家也就知道了構造函數是可以多個的。
在我們沒有顯示的定義構造函數的時候,編譯器會自動生成一個構造函數,這個構造函數是不帶參數的;當然,如果我們已經在類中顯示的定義了若幹或者一個構造函數,那麼編譯器就不會生成一個構造函數了。比如有一個類Class A;
1 class A{ 2 public: 3 A(int a){ 4 b=a; 5 cout<<b; 6 } 7 private: 8 int b; 9 };
在這個類中,我定義了一個帶有一個整形參數的構造函數,這就意味著如果我們要New一個新的對象只能傳遞一個int參數。如果不傳遞參數就會報錯,這也間接說明瞭,定義了構造函數就不會參數預設構造函數了。
所以,如果我們需要一個無參數的構造函數,就必須顯示的定義。一般來說,定義了一個帶參數的構造函數就要定義無參數的構造函數,這主要從安全和方便的角度來考慮的。因為我們經常是A x=new A();如果沒有定義無參數構造函數,我們可能連錯在哪裡都不知道。
這裡說到了構造函數的主要功能是初始化成員數據。上面已經提供了一種初始化方式,還有一種初始化方式是class A:b(5){};
需要註意的是在C++成員變數的初始化順序是按照聲明的順序保持一致的。而以構造函數的初始化順序無關。
一種特殊的構造函數:複製構造函數
註意,這裡是複製,而不是賦值。
複製構造函數其實就是對象的拷貝過程。例子如下。
1 A(const A &other){ 2 this->b=other.b; 3 cout<<this->b; 4 }
還有一種是賦值。下麵即是。其中x賦值到m。
1 A x(6),m=x;
談到複製構造函數的話,有必要強調一下深複製和淺複製的概念。也稱為深拷貝、淺拷貝。
先澄清我這裡的兩個概念,如果對象A複製到B,則稱A為原對象,B為新對象。
淺複製是指新對象所有變數都含有原對象的值,但是引用仍然指向原對象。
深複製是指新對象所有的變數都含原有對象的值,並且所有的引用也進行了複製。
這個怎麼理解呢?其實就是淺複製之後,引用還是對原對象的(所以一旦原對象指針釋放,新對象的指針就不知道指向何處了,野孩子就是這樣出現的)。而深複製,把引用也複製了(創建了自己的資源,原對象再折騰也影響不到我)。具體例子見下麵。
1 struct Test{ 2 char *ptr; 3 }; 4 void shallow_copy(Test &dest,const Test &source){//淺複製 5 dest.ptr=source.ptr; 6 } 7 void deep_copy(Test &dest,const Test &source){//深複製 8 dest.ptr=(char*)malloc(strlen(source.ptr)+1); 9 memcpy(dest.ptr,source.ptr,strlen(source.ptr)+1); 10 }
淺拷貝很容易造成程式崩潰,比如說原對象中有動態指針,如果淺拷貝,那麼新對象指向的還是原對象的指針,如果原對象釋放掉了.那麼新對象指向哪裡??
更多這方面的知識請查閱相關文章。
析構函數
與構造函數相對的是構造函數,構造函數是初始化對象成員,那麼析構函數就是釋放資源的,一般析構函數都是最後退出的時候執行的。
定義的話類似構造函數,在構造函數加一個~,比如~A(){};
另外析構函數無參數,無返回值,也只能有一個析構函數。
在繼承中,比如son類繼承parent類,son littleson;這個過程是先調用父類parent的構造函數,再調用son類的構造函數;析構函數則是一個相反的過程,先調用子類的析構函數,再調用父類的析構函數。其實這個我們從資源的分配和回收角度很容易理解。
談到資源的分配,我們知道編譯器自動分配是在棧中進行,程式員申請資源和釋放資源是在堆中進行的。
在C++中資源的申請有兩種不同的方式,New,malloc,想對應的釋放也有兩種方式delete,free.我們分析一下這兩種方式的異同。
相同的我們就不多說了,都可以進行資源的動態申請是他們最大的相同之處了,那麼異呢?
1、malloc是調用函數,而new 是運算符
2、malloc需要計算申請的位元組數,並轉化成相應類型;而new則是自動計算的。
3、malloc是不安全的,而New是安全的(申請的時候不會出現編譯出錯)如:int p=(int)malloc(sizeof(double));
4、maolloc需要庫文件的支持,函數肯定需要呀,而new 不需要,因為人家是運算符啊,你想想+須有庫文件就知道了嘛。
5、new會調用構造函數,delete調用析構函數。
那麼似乎new比malloc牛b多了,我們就不需要malloc了呢?
malloc是一種舊式的資源申請模式,現在都提倡new申請這是無疑的。但是有一種情況用malloc會取得比較好的效果,就是當程式在一次申請之後,可能會使用完畢需要再次申請的時候,因為有realloc啊。當然也可以用vector.
現在可以回答最開始的問題了,它會產生的成員函數至少包括:構造函數,析構函數,複製構造函數,取址運算符重載函數,賦值運算符重載函數,const取址運算符重載函數。