7

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?

4

2 回答 2

12

常量nullptr(类型为nullptr_t)和常量0都将隐式转换为任何指针类型的空值。因此,与任何一个进行比较都可以,并且在技术上是可以的。顺便说一句,这意味着不dynamic_cast返回任何一个,它返回特定指针类型的空值。

最好养成使用nullptr而不是0. 据我所知,只有正确的重载解决方案才真正需要(例如,一个重载 takeint和另一个 take char*)。为了一致性,避免0将是最好的。

“指针类型的空值”是什么意思?

考虑一个变量char * ptr。它的类型是(不出所料)char *。但类型nullptr是特殊类型nullptr_t。所以当我们写类似的东西时ptr = nullptr,一定会发生一些技术性的事情

  1. nullptr必须隐式转换为char *.
  2. 此转换的结果设置为 的新值ptr

的空值char *是转换为的nullptr结果char *。从概念上讲,它仍然是nullptr,但具有不同的类型 ( char *)。此空值不同于int *string *或任何其他指针类型的空值。我们倾向于将这些 null 值视为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*
}

或者在分配不相关的空值时:

char * c_ptr = nullptr; // Okay
int * i_ptr1 = nullptr; // Okay
int * i_ptr2 = c_ptr;   // COMPILER ERROR HERE
于 2013-05-16T15:10:44.757 回答
5

在布尔上下文中评估结果:

Base * p = get();

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

(这适用于任何版本的 C++。)

于 2013-05-16T15:09:22.393 回答