在c ++ 11中,dynamic_cast是返回nullptr还是0?

时间:2013-05-16 14:59:21

标签: c++11 dynamic-cast nullptr

我想查看dynamic_cast的结果。在c ++ 11(或c ++ 0x,对于支持nullptr的编译器),我应该与nullptr或0进行比较吗?

是否重要,如果是,为什么?

结果是编译器相关的吗?

2 个答案:

答案 0 :(得分:11)

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

最好养成使用nullptr而不是0的习惯。据我所知,只有正确的重载解析才真正有必要(例如,一次重载需要int,另一次需要char*。为了保持一致性,避免0将是最好的。

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

考虑变量char * ptr。它的类型是(不出所料)char *。但nullptr的类型是特殊类型nullptr_t。因此,当我们编写类似ptr = nullptr的内容时,必须发生一些技术性的事情

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

答案 1 :(得分:5)

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

Base * p = get();

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

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