建構函式:與類名相同的函數就是建構函式,沒有傳回值型別宣告。
建構函式的分類:無參建構函式、有參建構函式、賦值(拷貝)建構函式
Test() //無參建構函式定義Test(inta, int b) //有參建構函式定義Test(const Test &obj) //拷貝建構函式定義
下面分別討論三種建構函式
1. 無參建構函式
調用方法:Test t1, t2; //這個很好理解
2 有參建構函式
三種調用方法:
class Test5{ public: Test5(inta); Test5(int a, int b);}void main(){ Test5 t1(10); //c++編譯器預設調用有參建構函式 括弧法Test5 t2 = (20, 10); //c++編譯器預設調用有參建構函式 等號法Test5 t3 = Test5(30); //程式員手工調用建構函式 產生了一個對象 直接調用構造建構函式法}
3. 拷貝建構函式
為什麼要有拷貝建構函式——解決類對象的複製問題
對於普通類型的對象來說,它們之間的複製是很簡單的,例如:
int a=88;int b=a;
而類對象與普通對象不同,類對象內部結構一般較為複雜,存在各種成員變數。下面看一個類對象拷貝的簡單例子。
#include <iostream>using namespace std;class CExample {private: int a;public: CExample(int b) { a=b;} void Show () {cout<<a<<endl;}};int main(){ CExample A(100); CExample B=A; B.Show (); return 0;}
運行程式,螢幕輸出100。從以上代碼的運行結果可以看出,系統為對象B分配了記憶體並完成了與對象A的複製過程。就類對象而言,相同類型的類對象是通過拷貝建構函式來完成整個複製過程的。下面舉例說明拷貝建構函式的工作過程。
#include <iostream>using namespace std;class CExample {private:int a;public:CExample(int b){ a=b;}CExample(const CExample& C){a=C.a;}void Show (){cout<<a<<endl;}};int main(){CExample A(100);CExample B=A;B.Show ();return 0;} CExample(const CExample&C)
就是我們自訂的拷貝建構函式。可見,拷貝建構函式是一種特殊的建構函式,函數的名稱必須和類名稱一致,它的唯一的一個參數是本類型的一個引用變數,該參數是const類型,不可變的。例如:類X的拷貝建構函式的形式為X(X& x)。
當用一個已初始化過了的自訂類類型對象去初始化另一個新構造的對象的時候,拷貝建構函式就會被自動調用。也就是說,當類的對象需要拷貝時,拷貝建構函式將會被調用。以下情況都會調用拷貝建構函式:
一個對象以值傳遞的方式傳入函數體
一個對象以值傳遞的方式從函數返回
一個對象需要通過另外一個對象進行初始化。
如果在類中沒有顯式地聲明一個拷貝建構函式,那麼,編譯器將會自動產生一個預設的拷貝建構函式,該建構函式完成對象之間的位拷貝。位拷貝又稱淺拷貝,後面將進行說明。
自訂拷貝建構函式是一種良好的編程風格,它可以阻止編譯器形成預設的拷貝建構函式,提高源碼效率。
淺拷貝和深拷貝
在某些狀況下,類內成員變數需要動態開闢堆記憶體,如果實行位拷貝,也就是把對象裡的值完全複製給另一個對象,如A=B。這時,如果B中有一個成員變數指標已經申請了記憶體,那A中的那個成員變數也指向同一塊記憶體。這就出現了問題:當B把記憶體釋放了(如:析構),這時A內的指標就是野指標了,出現運行錯誤。
深拷貝和淺拷貝可以簡單理解為:如果一個類擁有資源,當這個類的對象發生複製過程的時候,資源重新分配,這個過程就是深拷貝,反之,沒有重新分配資源,就是淺拷貝。下面舉個深拷貝的例子。
#include <iostream>using namespace std;class CA{ public: CA(int b,char* cstr) { a=b; str=new char[b]; strcpy(str,cstr); } CA(const CA& C) { a=C.a; str=new char[a]; //深拷貝 if(str!=0) strcpy(str,C.str); } void Show() { cout<<str<<endl; } ~CA() { delete str; } private: int a; char *str;};int main(){ CA A(10,"Hello!"); CA B=A; B.Show(); return 0;}
深拷貝和淺拷貝的定義可以簡單理解成:如果一個類擁有資源(堆,或者是其它系統資源),當這個類的對象發生複製過程的時候,這個過程就可以叫做深拷貝,反之對象存在資源,但複製過程並未複製資源的情況視為淺拷貝。
淺拷貝資源後在釋放資源的時候會產生資源歸屬不清的情況導致程式運行出錯。
Test(Test &c_t)是自訂的拷貝建構函式,拷貝建構函式的名稱必須與類名稱一致,函數的形式參數是本類型的一個引用變數,且必須是引用。
當用一個已經初始化過了的自訂類類型對象去初始化另一個新構造的對象的時候,拷貝建構函式就會被自動調用,如果你沒有自訂拷貝建構函式的時候,系統將會提供給一個預設的拷貝建構函式來完成這個過程,上面代碼的複製核心語句就是通過Test(Test &c_t)拷貝建構函式內的p1=c_t.p1;陳述式完成的。
以上就是c++複習要點總結之三 ——建構函式的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!