2009-03-10 17 views
9

私はスマートポインタをさらに活用したいプロジェクトを持っているが保持していることが要求される「ポインタ」を返します。全体として、私はこの目標を達成しました。しかし、私は "ベストプラクティス"が何であるか分かりません。スマートポインタ

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

scoped_ptrshared_ptr(これは私が考える理想的な解決策になる)にアップグレードする適切な方法はないようです。私は彼らがなぜこれをしなかったのか理解しています。なぜなら、所有権の移転を許すので、std::auto_ptrのようないくつかの問題につながる可能性があります。

しかし、の場合は、の場合は所有権の移転が良いようです。だから、私の考えでは、このようなものです:

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

scoped_ptrshared_ptr両方がstd::auto_ptrから所有権を取るコンストラクタを持っているので、これが「OK」で動作します。

私の質問は、この良い習慣ですか?より良い解決策はありますか?

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

実際に私はそれがそれを得るためにいくつかの作業が必要だと思うことを除いても仕事ができる:唯一の真の選択肢は、私はこのような戻り値としてテンプレートテンプレートを使用している思い付くことができましたscoped_ptrと一緒に作業してください。

思考?

答えて

11

良い習慣です、実際such exampleにビャーネ・ストロヴストルップによって を示唆されました。

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

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(); 

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

もう一つの重要なポイント、shared_ptrは原子参照カウントを使用して、それがauto_ptrがないという単純な、まだ完全には効率的な仕事という はるかに遅いです。

P.S .: scoped_ptrは、auto_ptrのバージョンです。コピーできません。 にはデフォルトのコンストラクタがありません。これはauto_ptrの「あまり混乱しない」バージョンのようですが、shared_ptrと比べてtr1にはありません。一般的にはそこにあなたが他のスマートポインタ型としてstd::unique_ptrを使用することができるはずC++ 11でauto_ptr

+0

シングルスレッドビルドのshared_ptrは、アトミックな参照カウントを使用しません。 –

+0

そうですが、デフォルトではマルチスレッド版ではビルドが強化されています。 – Artyom

+2

auto_ptrにscoped_ptrを使用する利点は、ポインタをコピーしないことを明確にしたい場合です。あなたは単にscoped_ptrですることはできません。あなたの意図がauto_ptrと所有権の移転と同じように、あなたの意図を伝えることです。 –

3

ファクトリを作成して、ポインタを返すだけの場合は、そして、あなたの工場のユーザーは、このポインタをどのように、どこに置くか、自分で決められます。
スマートポインタの使用を強制する必要がある場合は、「間違った」ポインタを使用しないように選択肢を制限する必要があります。
だからboost :: shared_ptr。しかし、それをMyClassPtrまたはMyClass :: ptrにtypedefする方がよいでしょう。
まだ、工場は「新しい」ようです。私が望むとき、私はstd :: auto_ptrの新しい内部の結果を入れます。しかし、私はスマートなポインタが欲しくないときはいつも "リリース"を呼び出すように強制されたくありません。 std::auto_ptrを使用して

+0

trueですが、可能であればスマートポインタの使用を強制したいと思います。 –

+0

私は同意します、私たちはすべてここで大人です。裸のポインタを返し、コードのユーザに戻り値を最もよく捕らえる方法を決定させる。私は、auto_ptrからのshared_ptrのコンストラクタがなくなると考えています(auto_ptrは廃止予定です)。 –

+0

auto_ptrがC++ 0xで省略された場合、unique_ptrがそれを置き換えます。その後、unique_ptrを返すように切り替えます。 – Aaron

1

scoped_ptrを使用してのない多くの利点がstd::unique_ptrを取るコンストラクタを持っていません。そのようなリソースの内部リストを管理している場合は、おそらくstd::shared_ptrを使用したいと思うでしょう。