【问题标题】:In c++11, does dynamic_cast return nullptr or 0?在 c++11 中,dynamic_cast 返回 nullptr 还是 0?
【发布时间】:2013-05-11 13:15:00
【问题描述】:

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

重要吗?如果重要,为什么?

结果是否依赖于编译器?

【问题讨论】:

    标签: c++11 dynamic-cast nullptr


    【解决方案1】:

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

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

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

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

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

    char * 的空值是将nullptr 转换为char * 的结果。从概念上讲,它仍然是 nullptr,但具有不同的类型 (char *)。此空值不同于 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
    

    【讨论】:

    • 你能定义指针类型的空值是什么意思吗?这与 0 或 nullptr 有何不同?
    • @Patrick:我不会在评论中回答这个问题,而是将其附加到我的回答中。我认为它与问题足够相关。
    • 有趣。那么我在做if (nullptr == dynamic_cast<foo*>(p))的时候,是不是先把nullptr转换成foo*的null值,然后再做比较呢?
    • 理论上,指针的空值可能不是内存中的零位。但是整数值 0nullptr 在转换为指针类型时必须比较等于指针类型的空值,并且如果您在 boolean 上下文中评估指针,则指针类型的空值必须评估为假,非空值为真。然而,大多数环境将空指针存储为一堆零位。 :)
    【解决方案2】:

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

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

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

    【讨论】:

    • 我喜欢你的解决方案,但 Ken Wayne 更直接地回答了我的问题,所以我将他标记为答案。感谢您的回答!
    • 这可能是更好的使用形式(即使nullptr 一直存在),因为它不仅仅适用于与nullptr 相比的类型。它适用于任何具有空虚概念的类型,表示为转换为bool,就像optional&lt;T&gt; 一样。我也认为像std::function 这样的类型看起来更好,它与nullptr 相当,但实际上不是指针类型!
    猜你喜欢
    • 1970-01-01
    • 2019-01-28
    • 2021-09-27
    • 2011-04-01
    • 2011-11-04
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    相关资源
    最近更新 更多