Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

dynamic cast - In c++11, does dynamic_cast return nullptr or 0?

I want to check the result of dynamic_cast. In c++11 (or c++0x, for compilers that support nullptr), should I compare against nullptr or 0?

Does it matter, and if so, why?

Is the result compiler-dependent?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

  1. nullptr must be implicitly converted to char *.
  2. 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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...