C 拷貝 引用計數

2022-02-02 21:23:26 字數 1938 閱讀 2345

通常,我們會按如下方式書寫拷貝建構函式:

class lif  // 預設建構函式

lif(const lif& l) : lif(l.lif) {} // 拷貝建構函式

private:

int lif;

};

這是正確的。但是,如果資料成員包含指標型別的話,這種寫法就很危險了。

class lif  // 為lif動態分配記憶體

lif(const lif& l) : lif(l.lif) {} // 拷貝建構函式

~lif()

private:

int* lif;

};lif l1;

lif l2(l1); // 程式結束析構l2時,程式將崩潰

在拷貝l1生成l2的時候,我們的建構函式只是簡單的把l1lif成員的值賦予了l2lif,也就是說,它們儲存的都是l1構造時分配的位址,當兩者之中的某個物件被銷毀時,建構函式正常執行,資源被釋放,但之後如果另乙個物件也被析構,lif的資源就會被重複釋放,lif也就變成野指標。這種拷貝方式也稱為淺拷貝,即只拷貝空間,不拷貝資源。

為了防止指標型別的資料成員出現野指標錯誤,對應地便有了深拷貝操作,即在拷貝物件內容的同時為拷貝的內容分配新的資源。

class lif  // 為lif動態分配記憶體

lif(const lif& l) : lif(new int(*l.lif)) {} // 深拷貝建構函式

~lif()

private:

int* lif;

};lif l1;

lif l2(l1);

注意到,在上面的拷貝建構函式中,我們為新物件的lif成員分配了一塊新的記憶體,即完成了深拷貝。

從上面的例子可以得到兩種抽象的類行為:行為像值行為像指標

即類提供的建構函式是深拷貝,類的每個物件都有自己的乙份拷貝。對於這樣的類,它顯然需要:乙個深拷貝建構函式、乙個深拷貝賦值運算子過載、乙個可以釋放成員占用的資源的析構函式。

class lif 

lif(const lif& l) : lif(new int(*l.lif)) {}

lif& operator= (const lif& l)

~lif()

private:

int* lif;

};

即類提供的是淺拷貝,但由於可能有多個物件成員值相同一段記憶體,所以我們不能在析構時簡單地釋放資源。為了解決淺拷貝帶來的野指標問題,需要引入一種技術——引用計數(reference count)。這也是c++11的智慧型指標shared_ptr的實現。

引用計數:

class lif 

lif(const lif& l) :

lif(l.lif), referencecount(l.referencecount)

lif& operator= (const lif& l)

lif = l.lif;

referencecount = l.referencecount;

return *this; }

~lif()

}private:

int *lif;

unsigned *referencecount;

};

C 引用計數寫時拷貝

寫時拷貝技術原理 寫時拷貝技術是通過 引用計數 實現的,在分配空間的時候多分配4個位元組,用來記錄有多少個指標指向塊空間,當有新的指標指向這塊空間時,引用計數加一,當要釋放這塊空間時,引用計數減一,直到引用計數減為0時才真的釋放掉這塊空間。當有的指標要改變這塊空間的值時,再為這個指標重新分配自己的空...

String淺拷貝 引用計數

當類裡面有指標物件時,進行簡單賦值的淺拷貝,兩個物件指向同一塊記憶體,存在崩潰的問題!為了解決這個問題,我們可以採用引用計數。在引用計數中,每乙個物件負責維護物件所有引用的計數值。當乙個新的引用指向物件時,引用計數器就遞增,當去掉乙個引用時,引用計數就遞減。當引用計數到零時,該物件就將釋放占有的資源...

引用計數的寫時拷貝

首先我們需要知道什麼是寫時拷貝,通俗的說,就是寫的時候再拷貝。那到底什麼才是寫時拷貝呢?舉乙個很簡單的例子,就是建立乙個string類的物件,然後用這個物件再拷貝出多個物件,當然指標也會拷貝過去,造成多個物件指向同一塊空間,當對某個物件進行讀操作時,不會發生什麼問題,但當需要對某個物件進行寫操作時,...