——複製構造函數用於將一個對象的值複製到新建立的對象中,用於初始化過程當中(包括按值傳遞參數),而不是常規的賦值過程當中函數
Class_name(const Class_name &)
StringBad ditto(motto); // calls StringBad(const StringBad &) StringBad metoo = motto; // calls StringBad(const StringBad &) StringBad also = StringBad(motto); // calls StringBad(const StringBad &) StringBad * pStringBad = new StringBad(motto) // calls StringBad(const StringBad &)
中間兩種聲明可能會使用複製構造函數直接建立metoo和also,也可能使用複製構造函數生成一個臨時對象,而後將臨時對象的內容賦給metoo和also,這取決於具體的實現spa
——默認的複製構造函數逐個複製非靜態成員(成員複製也稱爲淺複製),複製的是成員的值指針
StringBad sailor = sports; //等效於 StringBad sailor; sailor.str = sports.str; sailor.len = sports.len;
只是因爲私有成員是沒法訪問的,所以後面的代碼不能經過編譯對象
靜態對象不受影響,由於它們屬於整個類,而不是各個對象blog
默認的複製構造函數不說明其行爲(全盤複製),若是須要在構造函數中修改類靜態數據成員,這時就會發生錯誤生命週期
解決辦法:提供一個顯示覆制構造函數內存
StringBad::StringBad(const String &s) { num_strings++; // static int num_strings聲明在類中 ... // imported stuff to go here }
若是類中包含這樣的靜態數據成員,即其值將在新對象被建立時發生變化,則應該提供一個顯示覆制構造函數字符串
隱式複製構造函數的淺複製(複製指針)致使的內存問題原型
解決辦法:定義一個顯示覆制構造函數,進行深度複製編譯器
StringBad::StringBad(const StringBad &st) { num_strings++; // handle static member update len = st.len; // same length str = new char [len + 1]; // allot space std::strcpy(str, st.str); // copy string to new location ... }
複製字符串並將副本的地址賦給str成員
若是類中包含了使用new初始化的指針成員,應當定義一個複製構造函數,以複製指向的數據,而不是指針,這被稱爲深度複製。複製的另外一種形式(成員複製或淺複製)只是複製指針值。淺複製僅淺淺地複製指針信息,而不會深刻「挖掘」以複製指針引用地結構