2012-03-15 11 views
5
void f(boost::shared_ptr<int> ptr) 
{ 
    if (ptr) // should we check? 
     // do something 
} 

void f2(int *p) 
{ 
    if (p) // good practice to check before using it 
     // do something 
} 

質問:shared_ptrを使用する前に検証する必要がありますか?boost :: shared_ptrまたはstd :: shared_ptrを使用する前にチェックする必要がありますか?

+0

参照の数をチェックするのに** use_count **関数を使用するだけで、チェックすることはありません。 – softghost

答えて

0

はい。 shared_ptrは、割り当てられたメモリを解放するタイミングを知って、そのメモリへの参照をカウントすることによって、あなたに利益をもたらします。あらかじめヌルではないことを事前に知る方法がないと仮定して、使用前に有効かどうかを検証する必要がありますが、shared_ptrを使用しているかどうかの問題の横にあります。

+2

これは一般的なアドバイスですが、他のポインタと同様に、ポインタがプログラム/クラスの不変のためにヌルにならない場合は、チェックする必要はありません。例えば、プライベートメンバの共有ポインタがコンストラクタで設定され、チェックされてから再割り当てされない場合、各メンバ関数呼び出しでそれをチェックする必要はありません。 –

+0

アンドレが正しいです。 – Almo

+0

@André:または、それは 'assert'でチェックする必要があります。 – ildjarn

5

いいえ有効である必要がある機能の契約にあれば、呼び出し元にバグがあるという事実に注意を促す最も簡単な方法はクラッシュすることです。できるだけ早く失敗してください。

+0

この問題は、技術的にはUBのみを引き起こすことになります。 _observable_バグ、まれにクラッシュは保証されません。 – ildjarn

+2

@ildjarn:「できるだけ早く失敗する」 - 「アサートする」。 :) – Xeo

+0

それはまさに私がしているので+1。無能でプログラマーではない教授が運営する大学のプログラミングコースでは聞き取れない典型的なスマートなものです。 – ceztko

3

普通のプログラム実行中に実際にshared_ptrがヌルであるかどうかによって異なります。そうでない場合は、ユーザーの前提条件として責任を押してfとし、おそらくassert(ptr);とします。それはshared_ptrにのみ適用されるのではなく、実際にポインタが使用されることに注意してください。おそらくここでの参照を使用してください。

+0

私は特に参照パラメータb/cを持つ関数を提供することによって質問を列挙しません。参照は空のポインタを指すべきではなく、常に参照を確認する必要はないと仮定します。しかし、それでも何とか無効にすることができます。 – q0987

2

は、シナリオによって異なります。

f()は、誰かがそうあなたがチェックする必要があり、あなたを渡すかもしれないものを制御することはできませんパブリック関数/ API関数である場合。

この関数がプライベートメンバー関数であるか、有効なポインタを必要とすると文書化されている場合は、assertを使用します。リリースビルドでオーバーヘッドが発生せず、デバッグビルドですぐに問題を表示します。

void f(shared_ptr<T> ptr) 
{ 
    assert(ptr && "ptr is null!"); 

    ..... 
} 
+1

デバッグとリリースで異なる動作をするため、ランタイム値の検証のためのアサートを嫌う。アサーションは、ランタイムチェック用ではなくアプリケーションインバリアント用に予約する必要があります。 –

0

レッツは言う:あなたのvoid foo(shared_ptr<int> ptr)は汎用ライブラリであり、あなたは、実行時にユーザーに知らせたいnullptr値がサポートされていないことを(例外をスロー)、またはそれは異なるコードパスで処理されている場合、はい、それは正しいですそれを確認する。 shared_ptrをfoo()のどこかに格納する必要がなく、その関数がヌルポインタをサポートしないようにする必要がある場合は、リファレンスを渡すだけです(例:void foo(int &integer))。私が知っているコンパイラでは、参照はほとんどの場合、null以外のポインタです(多くの場合、最適化の選択に依存します)。