単にif(pointer)
と書くことでNULL
でないことを指すポインターをチェックするのは安全ですか、それともif(pointer != NULL)
を使用する必要がありますか?
あなたはできる; NULLポインターは暗黙的にブール値のfalseに変換されますが、非NULLポインターはtrueに変換されます。 C++ 11標準のブール変換:に関するセクション
算術のprvalue、スコープのない列挙、ポインター、またはメンバー型へのポインターは、
bool
型のprvalueに変換できます。ゼロ値、nullポインター値、またはnullメンバーポインター値はfalse
に変換されます。その他の値はtrue
に変換されます。タイプstd::nullptr_t
のprvalueは、タイプbool
のprvalueに変換できます。結果の値はfalse
です。
はい、できます。
これは、C++標準変換の一部であり、ブール変換句に該当します。
§4.12ブール変換
算術のprvalue、有効範囲なし列挙、pointer、またはメンバー型へのポインターは、bool型のprvalueに変換できます。 ゼロ値、nullポインター値、またはnullメンバーポインター値はfalseに変換されます。他の値はtrueに変換されます。 std :: nullptr_t型のprvalueはbool型のprvalueに変換できます。 ;結果の値はfalseです。
はい、できます。実際、慣れると、読み書きが簡単になるため、if(pointer)
を使用することを好みます。
また、C++ 11にはnullptr
よりも優先されるNULL
が導入されていることに注意してください。
質問に回答しましたが、ポイントを追加したいと思います。
私は常にif(pointer)
の代わりにif(pointer != NULL)
とif(!pointer)
の代わりにif(pointer == NULL)
を好むでしょう:
バグチェックコードを記述する可能性が低くなります。等値チェック演算子==
のスペルを=
と間違えた場合if(pointer == NULL)
はつづりが間違っている可能性がありますif(pointer = NULL)
だからそれは避けます。最善はif(pointer)
です。
(私はいくつかの 1つの答えでヨーダの条件 を提案しましたが、それは別の問題です)
while (node != NULL && node->data == key)
についても同様に、while (node && node->data == key)
を書くだけです。これは私にとってより明白です(短絡を使用することを示しています)。
はい、できます。値をゼロと暗黙的に比較する機能はCから継承されており、C++のすべてのバージョンにあります。 if (!pointer)
を使用して、ポインターのNULLを確認することもできます。
NULLポインターの関連するユースケースは次のとおりです。
ダイナミックキャスト。基本クラスポインターを特定の派生クラス1(再度回避しようとする必要がありますが、必要な場合があります)へのキャストは常に成功しますが、派生クラスが一致しない場合はNULLポインターになります。これを確認する1つの方法は
Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);
if(derived_ptr != nullptr) { ... }
(または、できればauto derived_ptr = ...
)。さて、これは悪いです。なぜなら、それは安全ガードif
ブロックのスコープ外に(おそらく無効、つまりnull)派生ポインタを残すからです。 C++ではブール変換可能な変数を導入できるため、これは必要ありませんif
- condition内:
if(auto derived_ptr = dynamic_cast<Derived*>(base_ptr)) { ... }
これは短くてスコープセーフであるだけでなく、意図がはるかに明確です:別のif条件でnullをチェックすると、読者は「OK、だからderived_ptr
はnullであってはいけません...まあ、なぜnullでしょうか?」一方、1行バージョンでは、「base_ptr
を安全にDerived*
にキャストできる場合は、それを使用して...」と非常にわかりやすく説明しています。
同じことは、ポインターを返す他の可能性のある障害操作でも同様に機能しますが、IMOでは一般的にこれを避ける必要があります。ポインターではなく、失敗する可能性のある操作の結果の「コンテナー」としてboost::optional
のようなものを使用することをお勧めします.
したがって、nullポインターの主なユースケースを暗黙的なキャストスタイルのバリエーションで常に記述する必要がある場合、一貫性の理由でalwaysこのスタイルを使用する、つまりI ' d if(ptr)
よりもif(ptr!=nullptr)
を推奨します。
私は広告で終わらせなければならないのではないかと思います:if(auto bla = ...)
構文は、実際にはrealのような問題の解決法に少し面倒な近似です:pattern matching。最初に何らかのアクション(ポインターのキャストなど)を強制してから、失敗があるかもしれないと考えるのはなぜですか?つまり、それはばかげていますね。食べ物があり、スープを作りたいみたいです。柔らかい野菜である場合は、ジュースを抽出するタスクをアシスタントに渡します。最初にそれを見ないでください。あなたがジャガイモを持っているとき、あなたはまだあなたのアシスタントにそれを与えますが、彼らは失敗のメモであなたの顔にそれを平手打ちします。ああ、命令型プログラミング!
はるかに良い:あなたが遭遇する可能性のあるすべてのケースをすぐに検討してください。その後、それに応じて行動します。ハスケル:
makeSoupOf :: Foodstuff -> Liquid
makeSoupOf p@(Potato{..}) = mash (boil p) <> water
makeSoupOf vegetable
| isSoft vegetable = squeeze vegetable <> salt
makeSoupOf stuff = boil (throwIn (water<>salt) stuff)
Haskellには、実際に重大な障害の可能性がある場合(および他の多くの場合)のモナド用の特別なツールもあります。しかし、これはそれらを説明する場所ではありません。
⟨/advert⟩
はい。実際、そうすべきです。 セグメンテーションフォールト を作成するかどうか疑問に思っている場合は、作成しません。
はい、もちろん!実際、if(pointer)の書き込みは、if(pointer!= NULL)よりも便利な書き込み方法です。1。デバッグが簡単2.わかりやすい3.誤ってNULLの値が定義されている場合、また、コードはクラッシュしません