web-dev-qa-db-ja.com

std :: shared_ptrでnullをチェックします

使用する前にspnullであるかどうかを確認する必要があるかどうか疑問に思っていました。私が間違っている場合は修正しますが、エイリアスを作成してもrefカウンターは増加しません。したがって、埋め込みポインターが以前にリセットされたかどうかわからない共有ポインターで作業しているメソッドに入ることにより、..これを仮定?

Class::MyFunction(std::shared_ptr<foo> &sp)
{    
    ...  
    sp->do_something();  
    ...  
}
35
Nostradamus

ほとんどの共有ポインターは、この点で通常のポインターとまったく同じです。 nullを確認する必要があります。機能に応じて、使用に切り替えることができます

_void myFunction( Foo const& foo );
_

、およびポインターを逆参照することによって呼び出します(ポインターがnullでないことを確認する責任を呼び出し側にプッシュします)。

また、関数が共有ポインタを取るようにするのはおそらく悪い習慣ですnlessいくつかの特別な所有権セマンティクスが含まれます。関数が関数の期間中にポインタを使用するだけで、関数を変更したり所有権を取得したりしない場合、呼び出し元により少ない制約を課すため、生のポインタがおそらくより適切です。 (しかし、これは関数が何をするのか、そして共有ポインターを使用する理由に大きく依存します。そしてもちろん、共有ポインターへの非const参照を渡したという事実は、あなたがそれを修正しようとしていることを前提としています、そのため、共有ポインタを渡すことが適切な場合があります。)

最後に、共有ポインターのさまざまな実装により、nullのチェックが多少なりとも難しくなります。 C++ 11では、_std::shared_ptr_を使用して、当然のことながらnullptrと自然に比較できます。ただし、Boostの実装はこの点で少し壊れています。単に_0_またはNULLと比較することはできません。比較のために空の_boost::shared_ptr_を作成するか、その上でgetを呼び出して、結果の生のポインターを_0_またはNULLと比較する必要があります。

17
James Kanze

std::shared_ptr は、全体としてまだポインターであり(クラスのようなポインターにカプセル化されています)、実際には 内部的にnullptrになるように構築される です。それが起こると、次のような式:

ptr->
*ptr

未定義の動作につながります。ええ、もしポインターがnullptrであることを期待しているなら、 その値をチェックする で:

ptr != nullptr

または

!ptr

(その operator bool に感謝)。

46
Shoe

Shared_ptrを参照として渡す意味はありません。

boost::shared_ptr<T>.get()経由で内部オブジェクトを取得し、nullptrを確認できます

関連する:stdに移動します:)

Edit:これは実装です: http://www.boost.org/doc/libs/1_55_0/boost/smart_ptr/shared_ptr .hpp そして、ここにSO refまたはrefなしのスレッド: 参照によってshared_ptrを渡す必要がありますか?

Cx11の場合は移動セマンティクスを使用し、それ以外の場合は参照を渡すより遅い2つのintをコピーしますが、このレベルの最適化の誰かはいつですか?

3
Samuel

この質問に対する一般的な答えはありません。他のポインタと同じように扱う必要があります。 nullかどうかわからない場合は、テストします。それが決してヌルではないと信じるなら、assert()それがヌルではないことを直接使用してください。

shared_ptrへの参照を持っている、またはshared_ptrを持っているという事実は、ここでは影響を与えません。

2
Angew