C++深入理解(7)------類和動態分配內存(讀書筆記)

    在類內給成員變量分配內存使用new和delete中最常遇到的問題就是內存泄漏,造成這樣的原因往往是不對應,而且對C++的構造函數和析構函數不是很瞭解。C++會默認提供下面的函數:

    • 默認構造函數,如果沒有定義構造函數:
    • 默認析構函數,如果沒有定義;
    • 複製構造函數,如果沒有定義;
    • 賦值運算符,如果沒有定義:
    • 地址運算符,如果沒有定義。

    如果沒有構造函數就會存在提供默認構造函數,如果定義了,就不會提供,但是複製構造函數是默認隱藏提供的,而且賦值運算符,即將一個類對象賦值給同類的另一個對象。這裏分別講解需要注意的要點。

1、複製構造函數:複製構造函數用於將一個對象複製到另一個對象,其原型爲: Classname (const Classname &);

    需要知道何時被使用,其使用的地方大致集中在3處:在用一個對象給另一個對像用=初始化時;在傳入實參的時候會默認複製一個副本,調用複製構造函數;在函數返回值的時候也會返回副本,即調用一個複製構造函數。第二第三個都比較好理解,着重說一下第一個,因爲涉及到好多的初始化方式:

StringBad ditto (motto) ;         // calls StringBad (const StringBad A)
StringB admetoo = motto;          // calls StringBad (const StringBad &)
StringBad also = StringBad(motto); // calls StringBad (const StringBad &)
StringBad * pStringBad = new StringBad (motto);

    以其中的第二條作爲例子,說下過程,這裏首先調用admetoo的複製構造函數,並把motto作爲參數穿進去,將motto的所有成員變量的值都傳給admetoo的成員變量,這樣看上去兩者就有相同的值了。

    隱式的構造函數會帶來很多不便,隱式的複製構造函數會將原對象的屬性值原封不動的複製給新對象,這樣在複製指針的時候實際上覆制的爲同一個指針,當操作被複制的新對象的指針後,原來對象的指針也會受到影響。所以在一個類中含有指針,或者含有靜態變量,或者在構造函數中使用new的一般都要顯示的重新定義複製構造函數(此過程被叫做深度複製)。

2、默認的賦值運算符:Class_name & Class_name::operator=(const Class_name &) ;

    雖然與複製構造函數稍有差別,但是在使用=的時候,實際是將原對象的數據賦值給新對象,新對象的指針等數據依然是原對象的值,會導致指針的不恰當操作。

//這種方式是:用有參數的和沒參數的構造函數分別定義兩個對象,然後讓對象1給對象2賦值
StringBad headlinel("CeleryS talks at Midnight");
StringBad knot;
knot = headlinel;    // assignment operator invoked

     其最標準的寫法如下:

StringBad & StringBad::operator = (const StringBad & st)
{
if (this == &st)   //object assigned to itself
return *this;     // all done
delete [] str;     // free old string
len = st.len;
str = new char [len + 1 ]; // get space for new string
std :: strcpy(str, st.str ); // copy the string
return *this ;         // return reference to invoking
}

    其實說到底就是在重載=,當然還可以傳入不同的參數來重載出不同的運算符,如傳入char*,就可以將char*賦值給stringbad。

3.包含類成員的類的逐成員賦值:

    如果類包含多個類,但是這些類都需要new屬性,那麼還需要在爲這個大類重寫複製構造函數嗎?答案是不用的,這個類是有一定的智能型的,根據組件類的複製構造函數去逐個賦值。

        總結來說,當構造函數中包含new等動態分配內存的操作時,就要對賦值構造函數,賦值運算符等進行顯示的定義,從而進行深度複製,防止使用默認的構造函數,使指針操作異常。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章