Sowohl die Konstante nullptr
und die Konstante 0
(die vom Typ nullptr_t
ist) werden implizit In den Nullwert eines beliebigen Zeigertyps konvertieren. Der Vergleich mit beiden wird funktionieren und ist technisch in Ordnung. Übrigens bedeutet dies, dass dynamic_cast
weder eins zurückgibt noch den Nullwert für den bestimmten Zeigertyp zurückgibt.
Es ist wahrscheinlich am besten, sich angewöhnen, nullptr
statt 0
zu verwenden. Soweit ich weiß, ist es nur wirklich notwendig für die richtige Überladung Auflösung (z. B. eine Überladung dauert int
und eine andere dauert char*
). Aus Konsistenzgründen ist es am besten, 0
zu vermeiden.
Was meine ich mit "der Nullwert eines Zeigertyps"?
Betrachten Sie eine Variable char * ptr
. Es ist Typ (nicht überraschend) char *
. Aber der Typ nullptr
ist der spezielle Typ nullptr_t
. Also, wenn wir so etwas wie ptr = nullptr
schreiben, müssen einige technische Dinge passieren
nullptr
muss implizit in char *
umgewandelt werden. Das Ergebnis dieser Konvertierung wird als neuer Wert ptr
festgelegt.
Der Nullwert für char *
ist das Ergebnis der nullptr
zu char *
umwandelt. Konzeptionell ist es immer noch nullptr
, aber mit einem anderen Typ (char *
). Dieser Nullwert unterscheidet sich von dem Nullwert von int *
oder string *
oder einem anderen Zeigertyp. Wir neigen dazu, diese Nullwerte als nur nullptr
(oder 0
) zu denken, aber jeder ist wirklich ein unterschiedlicher Wert von einem anderen Typ. (Die gleiche Konvertierung erfolgt übrigens zum Vergleich mit ==
).
Obwohl dies wie Erbsenzählerei Details klingen mag, ist es sehr wichtig, in der Überladungsauflösung:
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*
}
oder wenn nicht verwandt Nullwerte zuweisen:
char * c_ptr = nullptr; // Okay
int * i_ptr1 = nullptr; // Okay
int * i_ptr2 = c_ptr; // COMPILER ERROR HERE
Können Sie definieren, was Sie mit dem Nullwert eines Zeigertyps meinen? Wie unterscheidet sich das von 0 oder nullptr? – Patrick
@Patrick: Anstatt dies in einem Kommentar zu beantworten, füge ich es meiner Antwort bei. Ich denke, es ist relevant genug für die Frage. –
Interessant. Wenn ich also 'if (nullptr == dynamic_cast (p))' mache, wird 'nullptr' zuerst in den Nullwert von' foo * 'umgewandelt, und dann wird der Vergleich gemacht? –
Patrick