簡體   English   中英

正確使用std :: unique_ptr和std :: weak_ptr

[英]Correct use of std::unique_ptr and std::weak_ptr

在這種情況下,如何正確使用std::unique_ptrstd::weak_ptr

struct B;
struct A
{
    B* b;
    float f;

    A(float f, B* parent)
        : f(f), b(parent)
    {}
};

struct B
{
    A a;

    B(float f)
        : a(f, this)
    {}
};

我想用auto anB = std::unique_ptr<B>(new B(3.0f))創建一個B 我的猜測是A應該具有std::weak_ptr<B> b而不是原始指針,但是要創建std::weak_ptr我需要Bstd::shared_ptr ...
在這種情況下, A應該只保留其原始指針嗎?

提供的信息不足以解決壽命管理問題。

您已經提供了一些結構布局。 您尚未描述結構中的數據將如何使用,也沒有描述其壽命。

結構布局不能確定生存期 ,除非合理的結構布局將取決於數據生存期問題。

你說的是:“我有一些紅色的油漆,我想用它來油漆房間。我應該買什么房子?” 結構布局對於解決生命周期問題很有用,而油漆對於在房屋中油漆房間很有用,但是提供結構布局不會告訴您使用什么智能指針,房屋油漆的顏色也不會告訴您要買什么房子。

您需要考慮各種對象的壽命,並嘗試使其盡可能簡單, 然后使用使該管理變得容易的智能指針。

由於A沒有對B所有權,因此可以使用原始(無所有權)指針。 (但其壽命應比A更長)。

因此,當前,您對B / A的默認副本構造函數/賦值有問題,這可能會使A指向舊B

實際上,對於weak_ptrB應該進入shared_ptr而不是unique_ptr ,並且為了允許相同的簽名,它應該繼承自std::enable_share_from_this ...

從我們在評論中的談話,在我看來,分離關注點可能是有序的。

A是B的一個屬性。必須有B的規范存儲(控制生存期),並且B的索引(無所有權)需要按B的某些屬性排序(在這種情況下,一個B的)。

這主張兩個向量(或其他適當的容器),一個包含B,另一個包含對B的排序引用。

您當然可以將容器和索引包裝到另一個對象中以提供封裝(在下面的簡單示例中我沒有做到這一點):

#include <vector>
#include <algorithm>
#include <memory>
#include <functional>

// define the attribute
struct A
{
    float f;

    A(float f)
        : f(f)
    {}
};

// define the object    
struct B
{
    A a1;
    A a2;

    // no back-pointers
    B(float f, float f2)
        : a1(f)
          , a2(f2)
    {}
};


int main()
{
  using b_vec_type = std::vector<B>;

  // build the canonical store      
  b_vec_type bs = { B { 1, 2}, B { 5, 4 }, B { 3, 4 } };

  using a1_index_type = std::vector<std::reference_wrapper<B>>;

  // build the index
  a1_index_type index(bs.begin(), bs.end());

  // sort the index by the attribute we want      
  std::sort(index.begin(), index.end(), 
            [](const B& l, const B& r) {
              return l.a1.f < r.a1.f;
            });

  // now use the index:

  for (const auto& e : index)
  {
    // do something with the Bs, ordered by B::a1
    // e will be of type std::reference_wrapper<B>, which has
    // a conversion operator to B& already defined.
  }


  return 0;
}

暫無
暫無

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

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