Both the constant nullptr
(which is of type nullptr_t
) and the constant 0
will implicitly convert to the null value of any pointer type. So comparing against either one will work and is technically OK. By the way, this means that dynamic_cast
return neither one, it returns the null value for the particular pointer type.
It's probably best to get in the habit of using nullptr
rather than 0
. As far as I know, it's only really necessary for proper overload resolution (e.g. one overload takes int
and another takes char*
). For consistency, avoiding 0
will be best.
What do I mean by "the null value of a pointer type"?
Consider a variable char * ptr
. It's type is (unsurprisingly) char *
. But the type of nullptr
is the special type nullptr_t
. So when we write something like ptr = nullptr
, some technical things must happen
nullptr
must be implicitly converted to char *
.
- The result of this conversion is set as the new value of
ptr
.
The null value for char *
is the result of converting nullptr
to char *
. Conceptually, it's still nullptr
, but with a different type (char *
). This null value is distinct from the null value of int *
or string *
or any other pointer type. We tend to think of these null values as just nullptr
(or 0
), but each one is really a distinct value from a different type. (By the way, the same conversion happens for comparison using ==
).
Although this may sound like nitpicking details, it's very important in overload resolution:
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*
}
or when assigning unrelated null values:
char * c_ptr = nullptr; // Okay
int * i_ptr1 = nullptr; // Okay
int * i_ptr2 = c_ptr; // COMPILER ERROR HERE
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…