3

非常に多くのshared_ptrsを使用する代わりの方法を探していたところ、コメントセクションで優れた返信が見つかりました。

本当に共有所有権が必要ですか?立ち止まって数分間考えれば、オブジェクトの1人の所有者とそのユーザーの数を正確に特定でき、所有者の存続期間中にのみ使用されると確信しています。したがって、それを所有者のローカル/メンバーオブジェクトにし、それを使用する必要がある人に参照を渡すだけです。

これを実行したいのですが、問題は、所有オブジェクトの定義で、最初に所有オブジェクトを完全に定義する必要があるということです。たとえば、FooManager.hに次のものがあるとします。

class Foo; 
class FooManager
{
    shared_ptr<Foo> foo;
    shared_ptr<Foo> getFoo() { return foo; }
};

さて、上記のアドバイスを受けると、FooManager.hは次のようになります。

#include "Foo.h"
class FooManager
{
    Foo foo;
    Foo& getFoo() { return foo; }
};

これには2つの問題があります。まず、FooManager.hは軽量ではなくなりました。これを含むすべてのcppファイルは、Foo.hもコンパイルする必要があります。次に、fooが初期化されるタイミングを選択できなくなりました。FooManagerと同時に初期化する必要があります。これらの問題を回避するにはどうすればよいですか?

4

3 に答える 3

3

の共有所有権セマンティクスが必要ない場合はshared_ptr、別のスマートポインタコンテナの使用を検討してください。

あなたが与える例(所有権を持ち、所有権の譲渡がない1つのオブジェクト)ではboost::scoped_ptr、良い選択です。

Boostを使用したくない場合は、scoped_ptr実装が非常に簡単です。Boostのドキュメントで詳しく説明されており、その実装(boost / shared_ptr.hpp)は簡単です。

于 2010-03-25T02:07:06.043 に答える
3

shared_ptr(または任意のスマートポインター、あるいはダムポインター)を使用できますが、所有権を共有することはできません。

例えば

class Foo; 
class FooManager
{
  private:
    shared_ptr<Foo> foo;
  public:
    Foo& getFoo() { return *foo; }
};

(これは単なるスケッチです。まだsetFoo()が必要であり、おそらくgetFoo()はFoo *を返す必要があります。しかし重要なのは、軽量に戻り、fooがいつ作成されるかを制御できるということです。)

于 2010-03-25T02:11:07.463 に答える
2

pimpl イディオムを使用し、インライン展開をやめます。

FooManager.h:

class Foo;

class FooManager
{
   struct Impl;
   Impl *m_impl;
public:
   Foo& getFoo();

   FooManager();
   ~FooManager();
};

FooManager.cpp

#include "Foo.h"
#include "FooManager.h"

struct FooManager::Impl
{
   Foo* m_foo;
   int m_someothermember;
   FooManager::Impl() : m_foo(NULL), m_someothermember(0) {}
};

FooManager::FooManager() : m_impl(new FooManager::Impl())
{}

Foo& FooManager::getFoo()
{
   // Lazy initialization
   if( !m_impl->m_foo ) {
      m_impl->m_foo = new Foo;
   }
   return *m_impl->m_foo;
 }

 FooManager::~FooManager()
 {
    delete m_impl->m_foo;
    delete m_impl;
 }

既にブーストを使用scoped_ptrしているため、この例で行ったようにメモリを手動で管理するのではなく、実際のコードにこれを実装することをお勧めします。心に留めておくべき重要なことは、前方宣言は、ポインターの場合と同様に参照に対しても機能することです (これが機能した理由の一部ですshared_ptr)。

于 2010-03-25T02:25:01.430 に答える