空值指標

空值指標具有稱為空值指標常數的保留值,指出指標未指向任何有效的物件或函數。 在下列情況下,您可以使用空值指標:

  • 起始設定指標。
  • 代表條件,例如不明長度清單的結尾。
  • 指出從函數傳回指標時發生錯誤。

空值指標常數是求值為零的整數常數表示式。 例如,空值指標常數可以是 0 ,0L,或可以強制轉型為類型的這類表示式(void *)0. C++C++11 定義新的空值指標常數nullptr只能轉換為任何指標類型、指標至成員類型或布林類型。

您可以為空值指標常數指定下列任何值:

  • 0
  • 空值
  • C++nullptr

附註: NULL 是巨集。 在使用之前必須先定義它。

空值指標常數

0

您可以將整數常數表示式與值 0 搭配使用,或將表示式強制轉型為(void *)0作為空值指標常數。

空值

巨集 NULL 及值 0 相當於空值指標常數,但 NULL 是清除程式,因為它代表將常數用於指標的目的。

C++ 僅限 C++11 的開頭。

nullptr

nullptr是明確空值指標常數。 在 C++ 中,使用 0 或 NULL 來起始設定空值指標會有下列問題:

  • 對於超載函數,無法區分空值指標與整數 0。 例如,假設有兩個超載函數f(int)f(char*),電話f(0)解析為f(int)因為0轉換成整數類型,而不是指標類型。 請參閱 Example1。
  • 空值指標常數沒有安全類型名稱。 巨集 NULL 無法從0超載函數及錯誤偵測的常數。

為了解決空值指標常數的問題, C++11 引進了新的關鍵字nullptrnullptr常數可以從整數 0 識別為超載函數。 請參閱範例 2。

具有空值指標常數的nullptr值具有下列性質:

  • 它可以轉換為任何指標或指標至成員類型。
  • 它無法隱含地轉換為任何其他類型,但 bool 類型除外。
  • 它無法在算術表示式中使用。
  • 它可以與整數 0 進行比較。
  • 它可以在關聯式表示式中使用,以與的指標或資料進行比較std::nullptr_t類型。

如需如何使用的相關資訊,請參閱範例 3nullptr作為所有指標類型及比較表示式的起始設定元。

附註: 仍可接受將值 0 或 NULL 指派給指標。

Thenullptrkeyword 指定類型的常數 rvaluedecltype(nullptr). typedef 表示式為typedef decltype(nullptr) nullptr_t,其中nullptr_t是的 typedefdecltype(nullptr)定義於<cstddef>. 非類型範本參數及引數可以具有std::nullptr_t類型。 如果非類型範本參數屬於類型std::nullptr_t,對應的引數必須是類型std::nullptr_t請參閱範例 4。 如果非類型範本參數是下列其中一種類型,則對應非類型範本引數的類型可以是std::nullptr_t. 最後三種類型會進行空值指標轉換:

  • std::nullptr_t
  • 指標 (pointer)
  • 指向成員的指標
  • bool

使用時nullptr在異常狀況處理中,請注意throwcatch引數。 處理程式符合類型的異常狀況物件E如果處理程式的類型為cv Tconst T&.T是指向成員類型的指標或指標E屬於類型std::nullptr_t請參閱範例 5。

範例

範例 1. 此範例說明不適當使用超載函數的 NULL 常數:

#include <stdio.h>

void func(int* i){
   printf("func(int*)\n");
}

void func(int i){
   printf("func(int)\n");
}

int main(){
   func(NULL);
} 

假設您想要 main 函數呼叫func(int* i)因此,main函數呼叫func(int i)代替func(int* i)因為常數 NULL 等於整數 0。 常數 0 隱含地轉換為(void*)0,僅當func(int i)不存在。

範例 2. 此範例說明如何nullptr用於超載函數:

void f( char* );
void f( int );
f( nullptr );     // calls f( char* )
f( 0 );           // calls f( int )

範例 3. 下列表示式說明正確及不正確使用nullptr常數:

char* p = nullptr;     // p has the null pointer value 
char* p1 = 0;          // p has the null pointer value 
int a = nullptr;       // error 
int a2 = 0;            // a2 is zero of integral type
if( p == 0 );          // evaluates to true 
if( p == nullptr );    // evaluates to true 
if( p );               // evaluates to false
if( a2 == 0 );         // evaluates to true 
if( a2 == nullptr );   // error, no conversion
if( nullptr );         // OK, conversion to the bool type 
if( nullptr == 0 );    // OK, comparison with 0
nullptr = 0;           // error, nullptr is not an lvalue 
nullptr + 2;           // error

範例 4. 此範例說明非類型範本參數或引數可以具有std::nullptr_t類型:

typedef decltype(nullptr) nullptr_t;
template <nullptr_t> void fun1(); // non-type template parameter

fun1<nullptr>();      // non-type template arguments 
fun1<0>();            // error. The corresponding argument must be of type
                      // std::nullptr_t if the parameter is of type std::nullptr_t.

template <int* p> void fun2(); 
fun2<nullptr>();      //Correct

template<typename T> void h( T t );
h( 0 );                   // deduces T = int
h( nullptr );             // deduces T = nullptr_t
h( (float*) nullptr );    // deduces T = float*

範例 5. 此範例說明如何使用nullptr在異常狀況處理中:

int main() {
try {
   throw nullptr;
} catch(int* p) {  // match the pointer.
   return p == 0;
}
}

C++ 僅限 C++11 結尾。