我想檢查dynamic_cast的結果。在C++ 11(或C++ 0x,對於支持nullptr的編譯器),我應該比較nullptr還是0?在C++ 11中,dynamic_cast是否返回nullptr或0?
這有什麼關係,如果是這樣,爲什麼?
結果是編譯器依賴的嗎?
我想檢查dynamic_cast的結果。在C++ 11(或C++ 0x,對於支持nullptr的編譯器),我應該比較nullptr還是0?在C++ 11中,dynamic_cast是否返回nullptr或0?
這有什麼關係,如果是這樣,爲什麼?
結果是編譯器依賴的嗎?
無論是恆定nullptr
(其爲nullptr_t
類型的)和恆定0
將隱含轉換爲任何指針類型的空值。因此,與任何一個進行比較都可以工作,技術上也可以。順便說一句,這意味着dynamic_cast
既不返回一個,它返回特定指針類型的空值。
這可能是最好的習慣使用nullptr
而不是0
。據我所知,只有正確的超載分辨率纔是真正必要的(例如一個超載需要int
而另一個需要char*
)。爲了一致性,避免0
將是最好的。
「指針類型的空值」是什麼意思?
考慮一個變量char * ptr
。它的類型是(不出意外)char *
。但nullptr
的類型是特殊類型nullptr_t
。所以,當我們寫類似ptr = nullptr
,一些技術上的事必須發生
nullptr
必須被隱式轉換爲char *
。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
評估結果在布爾上下文:
Base * p = get();
if (Derived * q = dynamic_cast<Derived *>(p))
{
q->derived_method();
}
else
{
// *p isn't of type Derived
}
(該工作在C任何版本++)
我喜歡你的解決方案,但肯·韋恩更直接地回答我的問題,所以我將他標爲答案。感謝您的回答! – Patrick
這可能是更好的形式(即使'nullptr'總是存在),因爲它不僅僅適用於與'nullptr'比較的類型。它適用於任何具有空虛概念的類型,表示爲「bool」的轉換,例如「可選
你能定義一個指針類型的空值是什麼意思嗎?這與0或nullptr有什麼不同? – Patrick
@帕特里克:我不會在評論中回答這個問題,而是將其附加到我的答案中。我認爲這個問題足夠重要。 –
有趣。所以當我做'if(nullptr == dynamic_cast(p))'時,'nullptr'首先轉換爲'foo *'的空值,然後進行比較? –
Patrick