6

現在、大きなプロジェクトに取り組んでおり、weak_ptr代わりにを使用する必要がありshared_ptrます。

これが私の問題です。

属性を持つ House という名前のクラスがあります: vector<boost::shared_ptr<People>> my_people。このデータ メンバーを に変更しますvector<boost::weak_ptr<People>> my_people

私のゲッターは

vector<boost::shared_ptr<People>>& getPeople() const
{
    return my_people;
}

通常、単純なweak_ptrI で戻ることができますmy_people.lock();

しかし、私はベクトルを持っていますが、次のようなことをする方法がわかりません:

vector<boost::shared_ptr<People>>& getPeople() const
{
    for( vector<boost::weak_ptr<People>::iterator it = my_people.begin();
         it != my_people.end();
         ++it)
    {
        (*it).lock();
    }

    return my_people;
}

weak_ptr言い換えれば、 のベクトルを のベクトルとして返したいのshared_ptrです。出来ますか?または、ベクトルを返して、weak_ptr使用するすべてのlock()場所で使用する必要がありますか?

4

4 に答える 4

2

あなたの機能は合理的なスタートです:

vector<boost::shared_ptr<People>>& getPeople() const
{
    for( vector<boost::weak_ptr<People>::iterator it = my_people.begin();
         it != my_people.end();
         ++it)
    {
        (*it).lock();
    }

    return my_people;
}

ただし、呼び出し(*it).lock()は を作成しshared_ptrて破棄するだけで、ベクター要素の型は変更されず、ベクターを別の型として返すことはできません。

適切なタイプのベクトルを作成し、shared_ptr オブジェクトで埋めて、返す必要があります。

vector<boost::shared_ptr<People>> getPeople() const
{
    vector<boost::shared_ptr<People>> people(my_people.size());
    std::transform(my_people.begin(), my_people.end(), people.begin(),
                   boost::bind(&boost::weak_ptr<People>::lock, _1));
    return people;
}

これは の各要素を反復処理し、それmy_peopleを呼び出しlock()、結果を の対応する要素に代入しpeopleます。

期限切れのポインターが含まれていないことがわかっている場合は、my_peopleさらに簡単です。

vector<boost::shared_ptr<People>> getPeople() const
{
  vector<boost::shared_ptr<People>> people(my_people.begin(), my_people.end());
  return people;
}

これは、要素からpeople各要素を構築することによってベクトルを埋めます。違いは、このバージョンでは、が期限切れになった場合に例外がスローされることです。期限切れのweak_ptrが変換された場合、使用するバージョンはベクター に空を置きます。shared_ptrweak_ptrweak_ptrshared_ptrweak_ptrtransformshared_ptr

于 2012-10-15T20:42:59.887 に答える
1

どうですか:

vector<boost::shared_ptr<People>> getPeople() const
{
    vector<boost::shared_ptr<People>> res;
    for( vector<boost::weak_ptr<People>::iterator it = my_people.begin(); 
         it != my_people.end(); ++it)
        res.push_back(it->lock());
    return res;
}

また、必要に応じて、ヌル ポインターを除外することもできます。

もちろん、ローカル変数への参照を返すことはできないため、コピーを返す必要があります。代わりに次のことを行うことができます。

void getPeople(vector<boost::shared_ptr<People>> &res) const
{
    for( vector<boost::weak_ptr<People>::iterator it = my_people.begin(); 
         it != my_people.end(); ++it)
        res.push_back(it->lock());
}

戻りベクトルをコピーしないようにします。

于 2012-10-15T12:41:03.110 に答える
0

vector<weak_ptr<T> >vector<shared_ptr<T> >は 2 つの完全に異なるタイプであることに注意してください。

ただし、前者を受け入れて後者を返す関数を作成できます。

  template<class Ptrs, class WeakPtrs> 
  void lockWeakPtrs(const WeakPtrs &weakPtrs, Ptrs &ptrs)
  {
      BOOST_FOREACH (typename WeakPtrs::const_reference weakPtr, weakPtrs)
      {
          typename Ptrs::value_type ptr = weakPtr.lock();
          if (ptr) // if you want to drop expired weak_ptr's
              ptrs.insert(ptrs.end(), ptr);
      }
  }

次のように呼び出します。 lockWeakPtrs(myWeakVector, mySharedVector);

于 2012-10-15T12:45:51.547 に答える