c 迴圈引用

2021-08-07 23:32:06 字數 1748 閱讀 1881

雖然c++11引入了智慧型指標的,但是開發人員在與記憶體的鬥爭問題上並沒有解放,如果我門實用不當仍然有記憶體洩漏問題,其中智慧型指標的迴圈引用缺陷是最大的問題。

//

// main.cpp

// test

//// created by 杜國超 on 17/9/9.

//#include

#include

#include

using namespace std;

class cobjb;

class cobja

~cobja()

shared_ptr

m_pb; // 在a中引用b

};class cobjb

~cobjb()

shared_ptr

m_pa; // 在b中引用a }; int main()

我們可以看到在出main函式作用域之前兩個指標指向的記憶體並沒有釋放(指標指向的物件沒有呼叫析構函式),我門把當前的引用數列印出來為2這個沒有問題,為什麼在函式結束時沒有呼叫物件的析構函式呢?這就好像多執行緒之間的死鎖一樣,物件a想要析構但是發現物件b引用了自己所以就等待物件b析構不再引用自己,而b想要析構卻發現物件a引用了自又等待a析構如此就導致兩個指標指向的物件沒有析構釋放記憶體,這就是迴圈引用導致的記憶體問題。

如何證明這個結論呢,我們手動釋放掉兩個物件對對方的引用,就可以解除迴圈引用關係,正確析構物件了(把注釋部分**開啟)。執行結果:

我門可以看到,呼叫reset函式釋放引用關係後,指標的引用計數變為一,等到函式執行結束,兩個shared指標生命週期結束呼叫析構函式,物件的引用計數減為0,物件記憶體釋放。

但是如果每次都要手動解除引用來解決迴圈引用,那麼智慧型指標似乎變成了傻子指標了,這時候還有乙個東西能解決,那就是weak_ptr,它不會改變所共享的shared_ptr的引用計數,即使我門可以通過該指標訪問它所指向的物件。

//

// main.cpp

// test

//// created by 杜國超 on 17/9/9.

//#include

#include

#include

using namespace std;

class cobjb;

class cobja

~cobja()

void say()

shared_ptr

getpb()

public:

weak_ptr

m_pb; // 在a中引用b }; class cobjb ~cobjb() void say() shared_ptr

getpa() public: weak_ptr

m_pa; // 在b中引用a }; int main() if (tmppb->getpa()!= null) }

這樣就得到我門想要的結果了。最後說一句雖然智慧型指標帶來了很多方便,但是也要小心使用它仍然有很多坑等著我門,以後再作詳述。

c 互相引用導致無限迴圈引用的報錯

在寫乙個大的程式時,常常要定義很多類,每個類有各自的用途。乙個類很可能會包含另乙個類定義的成員變數。假如有乙個類a,乙個類b。類a有乙個成員變數b b。類b有乙個成員變數a a。這時我們在定義類a和類b時會分別在開頭時包含引用到的.h檔案。這樣會導致編譯出錯。具體例子如下 mutou.h檔案 如下 ...

迴圈引用問題

main.m 07 迴圈引用 created by kevin on 13 8 9.1.class的作用 僅僅告訴編譯器,某個名稱是乙個類 class person 僅僅告訴編譯器,person是乙個類 2.開發中引用乙個類的規範 1 在.h檔案中用 class來宣告類 2 在.m檔案中用 impo...

迴圈引用問題

3 迴圈的retain 問題人有寵物 狗 狗有主人 人 那麼使用在使用兩個類時,再用 import相互匯入 就會有問題 需要使用 class 但是當兩個類都要引用對方的物件進入自己的類做屬性時,記憶體洩露的另一種情況。解決辦法 其中乙個先釋放 但是還有殭屍物件的問題 另乙個解決辦法是乙個用 reta...