簡體   English   中英

weak_ptr在shared_ptr中的作用

[英]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_worldshared_ptr創建它的weak_ptr

弱指針不聲明資源的所有權,而只是引用它。 因此,它們不允許您以任何方式對資源進行操作,除了再次聲明所有權(使用weak_ptr::lock()方法)。 恕我直言,這種行為所需的最常見的現實生活情況是循環依賴和(較不頻繁)緩存。

使用共享指針進行的循環依賴只是事實上的內存泄漏,因為指針的相互引用計數永遠不會小於1:如果沒有別的東西擁有A,那么B仍然會這樣做,反之亦然。 弱指針不能“檢測”這種情況。 只是通過打破所有權循環,它不會讓麻煩進入。 您可能仍然通過鎖定弱指針來“連接鏈的末端”,但是您可能通過弱指針獲得的共享指針都不會持久存在。

緩存的問題是,緩存通常不應該影響緩存內容的生命周期,它不是緩存的職責。 但是,如果緩存將保存共享指針,那么您將無法終止緩存對象的生命周期而無需與緩存進行通信,這通常很不方便。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM