2017-05-22 5 views
1

私は現在、私には奇妙に見えるサードパーティのC++コードを使っています(私はC++ 11から始めました)。私はあなたが、例えばポインタをキャストすることができます知っているC++のSomeType *にNULLをキャストするのはどうですか?

SomeClass* someClassPtr = static_cast<SomeClass*>(NULL); 

:困惑私を残し、多くのことの一つは、いくつかのポインタ型にNULLからstatic_castの多くのインスタンスであります基本クラスのポインタから派生したクラスのポインタへと継承されますが、ここでは継承は全くありません。私の知る限り見ることができるように、これは十分なはずです:

SomeClass* someClassPtr = NULL; 

しかしNULLが特定のポインタ型にキャストされません。このコードの唯一の例は、ベクター及び他のコンテナでのポインタです:

SomeOtherClass.vecOfSomeClassPtr[i] = NULL; 

だから私の質問は以下のとおりです。

  • は、この単純に古いスタイル(あるいはCスタイル)ですnullptrがあった前からのコード?
  • 継承を使って作業するときにダウン/アップキャスト以外のものに必要なのは、NULLです。
  • また、何か完全に欠けていますか?

そして場合には私がこれまでに間違ったそれをもらっていない:
私が最初にそれが何かを破るかどうかを確認するために、NULLstatic_cast<type*>(NULL)のすべてのインスタンスを置き換え、後でnullptr:いいえ。 コンパイラは抗議しておらず、プログラムは期待どおりに機能しているようです。 は、しかし、私はそう、ポインタがトリッキー少しできそこないことができる知っている:

  • 私はおそらくnullptrの使用についてどのような落とし穴を見逃したのか?

PS:はい、私は検索を使用しました。はい、Cコードで同様の質問がありました。 これはC++のコードなので、何かを仮定するのではなく、確かに知りたかったのです。

+2

質問には多くの質問があります。 – user2079303

+0

私は将来を考えています。 – Floriel

答えて

4

C++のSomeType *にNULLをキャストするのはどうですか?

SomeClass* someClassPtr = static_cast<SomeClass*>(NULL); 

キャストは、この文脈では効果がありません。

は、しかし、より一般的に、それはオーバーロードが関与している他のいくつかの文脈では意味を持たない:

void stupidly_overloaded_function(int); 
void stupidly_overloaded_function(SomeClass*); 
void stupidly_overloaded_function(SomeOtherClass*); 

stupidly_overloaded_function(NULL); 

呼び出された機能?実際にはNULLの定義に依存します。 intが過負荷と呼ばれるか、またはあいまいさのためにコンパイルが失敗します。

キャストはコールを明確にすることができます

stupidly_overloaded_function(static_cast<SomeClass*>(NULL)); 

私は、これはnullptrを導入するための重要な理由だと思います。でもnullptrは、複数の異なるポインタのオーバーロードに対処することはできませんが、それは整数の間で明確ん:Cで

void not_quite_as_silly_overload(int); 
void not_quite_as_silly_overload(SomeClass*); 

not_quite_as_silly_overload(NULL); // might call either overload 
not_quite_as_silly_overload(nullptr); // unambiguously calls the pointer overload 

別のケースでは、このようなLinuxカーネルからcontainer_ofマクロとしてオブジェクトのサイズに関与するマクロ、次のとおりです。

define container_of(ptr, type, member) ({      \ 
     const typeof(((type *)0)->member) *__mptr = (ptr); \ 
     (type *)((char *)__mptr - offsetof(type,member));}) 

ここでは、NULLの代わりに0だけが使用されています。私はだと思います。これは、キャストなしでC++で実装できますが、C++ 11で導入されたdeclvalしか使用していないと考えています。


nullptrがあった前からこの単に古いスタイル(あるいはCスタイル)のコードですか?

いいえ、このような冗長なキャストにはユニバーサルスタイルはありませんでした。あなたの例には過負荷がないので、上記のケースはそれに当てはまりません。

継承を使用して作業するときにダウン/アップキャスト以外の目的にNULLを使用する必要がありますか?

いいえ、オーバーロードの解決に必要なのは(異なるポインタオーバーロードの場合もあります)。

+0

したがって、これらのキャストを関数呼び出しで置き換えるのに注意する必要がありますが、代入ではそのようにすることは避けてください。 – Floriel

+1

@Florielは同じタイプのポインタへの代入において確実に安全です。 'nullptr'を使用する限り、関数呼び出しのためにおそらく安全です。オーバーロードが失敗した場合は、ビルド時に表示されます。 – user2079303

関連する問題