【C++ 繼承 | 智能指針 02】weak_ptr

weak_ptr 詳解

#include <iostream>
#include <memory>

class CB;

class CA
{
public:
	CA() { std::cout << "CA()" << std::endl; }
	~CA() { std::cout << "~CA()" << std::endl; }

	void set_ptr(std::shared_ptr<CB> &ptr) { m_ptr_b = ptr; }

private:
	std::shared_ptr<CB> m_ptr_b;
};

class CB
{
public:
	CB() { std::cout << "CB()" << std::endl; }
	~CB() { std::cout << "~CB()" << std::endl; }
	void set_ptr(std::shared_ptr<CA> &ptr) { m_ptr_a = ptr; }

private:
	std::shared_ptr<CA> m_ptr_a;
};

int main()
{
	std::shared_ptr<CA> ptr_a(new CA());
	std::shared_ptr<CB> ptr_b(new CB());

	ptr_a->set_ptr(ptr_b);
	ptr_b->set_ptr(ptr_a);
	std::cout << ptr_a.use_count() << " " << ptr_b.use_count() << std::endl;
	return 0;
}

既然析構函數沒有調用,就說明ptr_aptr_b兩個變量的引用計數都不是0。

分析一下引用情況

#include <iostream>
#include <memory>

class CB;
class CA
{
public:
	CA() { std::cout << "CA()" << std::endl; }
    ~CA() { std::cout << "~CA()" << std::endl; }
    void set_ptr(std::shared_ptr<CB>& ptr) { m_ptr_b = ptr; }
private:
    std::shared_ptr<CB> m_ptr_b;
};

class CB
{
public:
    CB() { std::cout << "CB()" << std::endl; }
    ~CB() { std::cout << "~CB()" << std::endl; }
    void set_ptr(std::shared_ptr<CA>& ptr) { m_ptr_a = ptr; }
private:
    std::weak_ptr<CA> m_ptr_a;
};

int main()
{
	std::shared_ptr<CA> ptr_a(new CA());
    std::shared_ptr<CB> ptr_b(new CB());
    
    ptr_a->set_ptr(ptr_b);
    ptr_b->set_ptr(ptr_a);
    std::cout << ptr_a.use_count() << " " << ptr_b.use_count() << std::endl;
	return 0;
}

流程與上一例子大體相似,但是不同的是4這條引用是通過weak_ptr建立的,並不會增加引用計數。也就是說,CA的對象只有一個引用計數,而CB的對象只有兩個引用計數,當main函數返回時,對象ptr_aptr_b被銷燬,也就是1,3兩條引用會被斷開,此時CA對象的引用計數會減爲0,對象被銷燬,進而解決了引用成環的問題。

參考資料

1. 智能指針循環引用問題

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