[英]Role of weak_ptr in shared_ptr
我理解shared_ptr如何工作,除了weak_ptr的角色。 我理解它在那里檢測循環引用時引用計數不為零,但除此之外,我不明白它究竟是如何做到的。 它有什么作用?
另請參見: std :: weak_ptr何時有用? 為什么以及weak_ptr如何工作? 如何。
我將舉例說明我如何使用它,雖然我掀起的示例代碼有點令人費解,所以請耐心等待:
#include <vector>
#include <memory>
#include <ostream>
int main()
{
// Fill container with values 1-50. This container OWNS these values.
std::vector<std::shared_ptr<int>> owning_container;
for(int i = 1; i <= 50; ++i)
{
owning_container.emplace_back(std::make_shared<int>(i));
}
// Create a sepearate container that references all owned values that are multiples of 5.
std::vector<std::weak_ptr<int>> referencing_container;
for(std::shared_ptr<int> const& i : owning_container)
{
if((*i) % 5 == 0)
{
// Make weak_ptr that references shared_ptr
referencing_container.emplace_back(i);
}
}
// Go through the owned values and delete all that are multiples of 10.
for(auto it = owning_container.begin(); it != owning_container.end();)
{
std::shared_ptr<int> const& i = *it;
if(*i % 10 == 0)
{
it = owning_container.erase(it);
}
else
{
++it;
}
}
// Now go through the referencing container and print out all values.
// If we were dealing with raw pointers in both containers here we would access deleted memory,
// since some of the the actual resources (in owning_container) that referencing_container
// references have been removed.
for(std::weak_ptr<int> const& i_ref : referencing_container)
{
// Check if the shared resource still exists before using it (purpose of weak_ptr)
std::shared_ptr<int> i = i_ref.lock();
if(i)
{
std::cout << *i << std::endl;
}
}
return 0;
}
在這里,我們有一個包含一些共享資源的容器 - 在這種情況下為 - ( shared_ptr
),另一個容器需要引用( weak_ptr
)。 引用不擁有資源,只需要能夠訪問它( 如果存在) 。 為了判斷被引用的資源是否仍然存在,我們使用weak_ptr::lock()
將weak_ptr
轉換為shared_ptr
。 那些仍然存在的資源將具有lock()
返回的有效shared_ptr
。 那些不再存在的將返回null shared_ptr
。 shared_ptr
有一個operator bool()
,我們可以在嘗試使用它之前檢查它是否為null。
如果你制作的游戲中游戲中的每個對象都由game_object
代表,那么一個不太復雜的場景可能就是game_object
。 假設你有一種尋求敵人的邏輯,這需要一個目標game_object
來尋求。 使用上面的方法,你可以讓敵人抓住一個weak_ptr<game_object>
。 它不擁有這個game_object
。 如果其他東西殺死其目標,其目標應該死亡; 如果敵人持有一個shared_ptr
而不會陷入某種不穩定狀態。 這樣,如果敵人的目標仍然存活(可以通過鎖定weak_ptr
來檢查),它可以執行搜索邏輯; 否則它可以找到新的目標。 game_object
的“所有者”可能是某種類型的game_world
類 - 這將有一個shared_ptr<game_object>
的容器。 當敵人需要一個新目標時,它可以搜索這個容器並從game_world
的shared_ptr
創建它的weak_ptr
。
弱指針不聲明資源的所有權,而只是引用它。 因此,它們不允許您以任何方式對資源進行操作,除了再次聲明所有權(使用weak_ptr::lock()
方法)。 恕我直言,這種行為所需的最常見的現實生活情況是循環依賴和(較不頻繁)緩存。
使用共享指針進行的循環依賴只是事實上的內存泄漏,因為指針的相互引用計數永遠不會小於1:如果沒有別的東西擁有A,那么B仍然會這樣做,反之亦然。 弱指針不能“檢測”這種情況。 只是通過打破所有權循環,它不會讓麻煩進入。 您可能仍然通過鎖定弱指針來“連接鏈的末端”,但是您可能通過弱指針獲得的共享指針都不會持久存在。
緩存的問題是,緩存通常不應該影響緩存內容的生命周期,它不是緩存的職責。 但是,如果緩存將保存共享指針,那么您將無法終止緩存對象的生命周期而無需與緩存進行通信,這通常很不方便。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.