2013-05-16 4 views

答えて

10

nullptr定数(タイプnullptr_tである)と定数0両方う暗黙任意のポインタ型のnull値に変換します。だからどちらかと比較するとうまくいくでしょうし、技術的にはOKです。ところで、これはdynamic_castがどちらも返さないことを意味し、特定のポインタ型のnull値を返します。

0ではなくnullptrを使用する傾向があります。私が知る限り、過負荷の適切な解決には本当に必要なだけです(たとえば、1つの過負荷はint、もう1つはchar*です)。一貫性を保つために、0を避けるのが最適です。

「ポインタ型のNULL値」とはどういう意味ですか?

変数char * ptrとします。そのタイプは(意外にも)char *です。しかし、nullptrのタイプは特殊タイプnullptr_tです。我々はptr = nullptrのような何かを書くときに、いくつかの技術的な事が

  1. nullptrが暗黙的にchar *に変換する必要がありますが起こる必要があります。
  2. この変換の結果は、新しい値ptrとして設定されます。

char *のヌル値は、nullptrchar *に変換した結果です。概念的には、まだnullptrですが、異なるタイプ(char *)です。このヌル値はヌル値int *またはstring *または他のポインター型とは異なります。これらのヌル値はちょうどnullptr(または0)と考える傾向がありますが、実際にはそれぞれ異なるタイプの異なる値です。 (ところで、==を使って比較すると同じ変換が行われます)。

これはつべこべの詳細のように聞こえるかもしれないが、それはオーバーロードの解決に非常に重要です。

void foo(char * ptr) { ... } 
void foo(int i) { ... } 
void foo(nullptr_t ptr) { ... } 

int main() 
{ 
    foo(0); // Calls void foo(int), since 0 is an int 
    foo(nullptr); // Calls void foo(nullptr_t), since nullptr is a nullptr_t 
    foo(new char('c')); // Calls void foo(char *), since new char('c') is a char* 
} 

または無関係のnull値を割り当てる:

char * c_ptr = nullptr; // Okay 
int * i_ptr1 = nullptr; // Okay 
int * i_ptr2 = c_ptr; // COMPILER ERROR HERE 
+0

ポインタ型のヌル値の意味を定義できますか?これは0またはnullptrとどう違うのですか? – Patrick

+0

@Patrick:コメントでこれに答えるのではなく、私の答えに追加します。私はそれが問題に十分に関連していると思う。 –

+0

興味深い。ですから 'if(nullptr == dynamic_cast (p))'を実行すると 'nullptr'が最初に' foo * 'のヌル値に変換されて比較されますか? – Patrick

5

はブールコンテキストで結果を評価する:

Base * p = get(); 

if (Derived * q = dynamic_cast<Derived *>(p)) 
{ 
    q->derived_method(); 
} 
else 
{ 
    // *p isn't of type Derived 
} 

(これはC++のすべてのバージョンで動作します。)

+0

私はあなたのソリューションを好きですが、ケン・ウェインは、より直接的に答えました私の質問、私は答えとしてマークしています。ご回答有難うございます! – Patrick

+0

これはおそらく 'nullptr'と比較する型以上のもので動作するので、(nullptrが常に存在する場合でも)より良い形式です。それは 'bool'への変換として表現される空の概念を持つ任意の型に対して動作します。例えば' optional 'のようになります。 'nullptr'に匹敵するが、実際にはポインタ型ではない' std :: function'のような型のほうが良いと思います! –