C++11/std::shared_ptr - 循環引用問題

在C++11智能指針的使用過程中,一個很大的陷阱就是陷入了循環引用問題,這個問題類似於大型項目中兩個頭文件互相包含的問題,而在C++11中如果因爲使用智能指針而引發了循環引用問題,那麼其結果會導致智能指針無法釋放,導致動態內存泄漏。

1循環引用

下面是一個典型的循環引用示例:

class B;
class A {
public:
    std::shared_ptr<B> pointer_B;
    ~A() {
        std::cout << "A已經被刪除" << std::endl;
    }
};

class B {
public:
    std::shared_ptr<A> pointer_A;
    ~B() {
        std::cout << "B已經被刪除" << std::endl;
    }

};

int main()
{
    {
        std::shared_ptr<A> pointer_A(new A);
        std::shared_ptr<B> pointer_B(new B);
        pointer_A->pointer_B = pointer_B;
        pointer_B->pointer_A = pointer_A;
    }

    getchar();
    return 0;
}

上述兩個代碼中兩個智能指針pointer_A和pointer_B都不會被刪除,造成了內存泄漏。上述代碼存在循環引用問題,pointer_A和pointer_B引用計數爲2,在離開作用域之後,pointer_A和pointer_B的引用計數減爲1,但是並不會減爲0,導致了兩個智能指針都不會調用析構函數,造成了內存泄漏。

2 使用weak_ptr修復循環引用

在C++11中,要解決這種循環引用問題的一種方式是引入弱引用指針weak_ptr,weak_ptr主要用於監視shared_ptr,構造其引用計數不會加1,析構引用計數也不會減1,主要用於監測shared_ptr中所管理的指針資源是否存在。

使用weak_ptr修復循環引用問題如下:

class B;
class A {
public:
	std::shared_ptr<B> pointer_B;
	~A() {
		std::cout << "A已經被刪除" << std::endl;
	}
};

class B {
public:
	std::weak_ptr<A> pointer_A;// 將shared_ptr修改爲weak_ptr
	~B() {
		std::cout << "B已經被刪除" << std::endl;
	}

};

int main()
{
	{
		std::shared_ptr<A> pointer_A(new A);
		std::shared_ptr<B> pointer_B(new B);
		pointer_A->pointer_B = pointer_B;
		pointer_B->pointer_A = pointer_A;
	}

	getchar();
	return 0;
}

大家有興趣也可以訪問我的個站:www.stubbornhuang.com

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