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

邮差的信 提交于 2019-11-29 07:19:40

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

Evaluate the result in a boolean context:

Base * p = get();

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

(This works in any version of C++.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!