9

スマート ポインターをもっと活用したいプロジェクトがあります。全体として、私はこの目標に成功しています。ただし、「ベスト プラクティス」とは何かよくわからないことが 1 つあります。

基本的に、関数から「ポインター」を返したいのですが、ユーザーはそれをスマートポインターに保持する必要があります。それだけでなく、特定のスマート ポインター (共有とスコープ) を強制したくありません。

scoped_ptr問題は主に、aを aにアップグレードする適切な方法がないように思われることですshared_ptr(それが理想的な解決策だと思います)。所有権の譲渡が可能になり、そのような問題が発生する可能性があるため、彼らがこれを行わなかった理由を理解していstd::auto_ptrます。

ただし、この場合、所有権の譲渡は良い考えのようです。だから私の考えは次のようなものです:

// contrived example of factory pattern
std::auto_ptr<A> func() { return std::auto_ptr<A>(new A); }

と の両方が a から所有権を取得するコンストラクターを持っているscoped_ptrため、これは「問題なく」機能します。shared_ptrstd::auto_ptr

だから私の質問は、これは良い習慣ですか?より良い解決策はありますか?私が思いついた唯一の実際の代替手段は、次のようにテンプレート テンプレートを戻り値として使用することです。

// similar to above example
template <template <typename> class P>
P<A> func() { return P<A>(new A); }

これは実際にはうまく機能する可能性がありますが、それを機能させるにはいくつかの作業が必要だと思いますscoped_ptr.

考え?

4

3 に答える 3

11

実際、そのような例std::auto_ptrBjarne Stroustrup によって提案されました。

の移動セマンティクスはauto_ptr、それに対処するための適切なツールを提供します。

例えば:

auto_ptr<Foo> make_foo()
{
    return auto_ptr<Foo>(new Foo);
}

Foo *raw_pointer=make_foo().release();
shared_ptr<Foo> shared_pointer=make_foo();
auto_ptr<Foo> auto_pointer=make_foo();

戻るshared_ptrと、通常のポインターにフォールバックできなくなりauto_ptrます。auto_ptr常に共有にアップグレードできますが、他の方向にはアップグレードできません。

もう 1 つの重要な点は、shared_ptrアトミックな参照カウントを使用することです。これは、単純でありながら完全に効率的なジョブよりもはるかに低速ですauto_ptr

PS:貧乏人向けscoped_ptrの単なるバージョンですauto_ptr--- コピーできず、デフォルトのコンストラクターがありません。tr1 にないのauto_ptrと比べて、の「混乱の少ない」バージョンに似ています。一般に、以上shared_ptrを使用する利点はあまりありません scoped_ptrauto_ptr

于 2009-03-10T18:56:07.820 に答える
3

ファクトリを構築する場合は、ポインタを返すだけで問題ありません。ファクトリのユーザーは、このポインターをどこにどのように配置するかを自分で決定できます。
スマートポインターの使用を強制する必要がある場合は、「間違った」ポインターを使用したくないため、選択を制限する必要があります。
したがって、boost::shared_ptr. しかし、それを MyClassPtr または MyClass::ptr に型定義する方がよいでしょう。
それでも、工場は「新しい」ようです。必要に応じて、new の結果を std::auto_ptr の中に入れます。しかし、スマートポインターが必要ないときに、常に「リリース」を強制的に呼び出す必要はありません。

于 2009-03-10T18:26:17.063 に答える
1

C++11 ではstd::unique_ptr、他のスマート ポインター型にはstd::unique_ptr. そのようなリソースの内部リストを維持している場合は、おそらくstd::shared_ptr.

于 2011-10-18T02:20:25.487 に答える