c++ - define - 什麼是nullptr?



nullptr c++ header (7)

我們現在擁有許多新功能的C ++ 11。 一個有趣和令人困惑的(至少對我來說)是新的nullptr

好吧,不再需要討厭的宏NULL

int* x = nullptr;
myclass* obj = nullptr;

不過,我沒有得到nullptr工作方式。 例如, 維基百科文章說:

C ++ 11通過引入一個新的關鍵字來作為一個可區分的空指針常量來糾正這個問題:nullptr。 它的類型為nullptr_t ,它可以隱式轉換,並且可以與任何指針類型或成員指針類型進行比較。 除了bool以外,它不是可以隱式轉換的或者可以與整數類型進行比較。

它是一個關鍵字和一個類型的實例?

另外,你是否還有另一個例子(維基百科之外), nullptr優於舊的0

https://src-bin.com


Answer #1

另外,你是否還有另一個例子(維基百科之外), nullptr優於舊的0?

是。 這也是我們的生產代碼中出現的(簡化的)真實世界的例子。 它只是因為gcc能夠在交叉編譯到具有不同寄存器寬度的平台時發出警告(仍然不確定為什麼只有在從x86_64到x86的交叉編譯時警告warning: converting to non-pointer type 'int' from NULL ) :

考慮這個代碼(C ++ 03):

#include <iostream>

struct B {};

struct A
{
    operator B*() {return 0;}
    operator bool() {return true;}
};

int main()
{
    A a;
    B* pb = 0;
    typedef void* null_ptr_t;
    null_ptr_t null = 0;

    std::cout << "(a == pb): " << (a == pb) << std::endl;
    std::cout << "(a == 0): " << (a == 0) << std::endl; // no warning
    std::cout << "(a == NULL): " << (a == NULL) << std::endl; // warns sometimes
    std::cout << "(a == null): " << (a == null) << std::endl;
}

它產生這個輸出:

(a == pb): 1
(a == 0): 0
(a == NULL): 0
(a == null): 1

Answer #2

它是一個關鍵字和一個類型的實例?

這並不奇怪。 truefalse都是關鍵字,而文字則是類型( bool )。 nullptrstd::nullptr_t類型的指針字面值 ,它是一個prvalue(你不能用&來取它的地址)。

  • 4.10關於指針轉換說std::nullptr_t類型的prvalue是一個空指針常量,並且一個整型空指針常量可以轉換為std::nullptr_t 。 相反的方向是不允許的。 這允許為指針和整數重載函數,並且傳遞nullptr來選擇指針版本。 傳遞NULL0會令人困惑地選擇int版本。

  • nullptr_t轉換為整數類型需要reinterpret_cast ,並且具有與將(void*)0轉換為整型(映射實現定義)相同的語義。 reinterpret_cast不能將nullptr_t轉換為任何指針類型。 如果可能,請使用隱式轉換或使用static_cast

  • 該標準要求sizeof(nullptr_t)sizeof(void*)


Answer #3

NULL不一定是0.只要你總是使用NULL而不是0,NULL可以是任何值。 假設你編程一個具有平坦存儲器的馮諾依曼微控制器,它的中斷向量為0.如果NULL為0,並且在NULL指針處寫入,則微控制器崩潰。 如果NULL表示1024並且在1024處有一個保留變量,則寫入不會使其崩潰,並且可以從程序內檢測NULL指針賦值。 這在PC上是毫無意義的,但對於太空探測器,軍事或醫療設備來說,重要的是不要撞車。


Answer #4

nullptr不能被分配給一個integral type比如int,但只能是一個類型pointer ; 內置指針類型(如int *ptr或智能指針(如std::shared_ptr<T>

我認為這是一個重要的區別,因為NULL仍然可以分配給integral typepointer因為NULL是一個擴展為0的宏,它既可以作為int的初始值,也可以作為pointer


Answer #5

假設您有一個函數(f)被重載以同時使用int和char *。 在C ++ 11之前,如果你想用一個空指針來調用它,並且你使用了NULL(即值為0),那麼你會調用一個重載為int的指針:

void f(int);
void f(char*);

void g() 
{
  f(0); //calls f(int)
}

這可能不是你想要的。 C ++ 11用nullptr解決了這個問題; 現在您可以編寫以下內容:

void g()
{
  f(nullptr); //calls f(char*)
}

Answer #6

它是一個關鍵字,因為標準將會這樣指定它。 ;-)根據最新的公眾草案(n2914)

2.14.7指針文字[lex.nullptr]

pointer-literal:
nullptr

指針文字是關鍵字nullptr 。 它是std::nullptr_t類型的右值。

這很有用,因為它不會隱式轉換為整數值。


Answer #7

那麼,其他語言已經保留了類型實例的單詞。 Python,例如:

>>> None = 5
  File "<stdin>", line 1
SyntaxError: assignment to None
>>> type(None)
<type 'NoneType'>

這實際上是一個非常接近的比較,因為None通常用於沒有初始化的東西,但同時比較如None == 0是錯誤的。

另一方面,在普通的C中, NULL == 0會返回真正的IIRC,因為NULL只是一個返回0的宏,它始終是無效地址(AFAIK)。





nullptr