首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

C++11 nullptr 詳解:類型安全的空指針字面量,徹底替代 NULL/0

     編輯:C++ 入門

為什麼需要 nullptr?

C/C++ 歷史上用 `NULL` (宏) 或 `0` 表示空指針,但存在**類型安全缺陷**:

  • C: `#define NULL (void*)0` → `void*` 可隱式轉換為任意指針類型,但 C++ 禁止 `void*` 隱式轉換。
  • C++: `#define NULL 0` → `NULL` 本質是 `int`,導致重載決議錯誤。

經典重載決議錯誤示例

#include 
void f(int i)    { std::cout << "f(int)\n"; }
void f(void* p)  { std::cout << "f(void*)\n"; }

int main() {
    f(NULL);  // C++ 中 NULL=0 → 調用 f(int)!預期調用 f(void*)
    f(0);     // 同理,調用 f(int)
    f(nullptr); // 正確調用 f(void*)
    return 0;
}

輸出:

f(int)
f(int)
f(void*)

nullptr 特性

  • 關鍵字 (C++11),類型為 `std::nullptr_t`。
  • 可隱式轉換為**任意指針類型** (`T*`, `T* const`, `void*` 等) 和**指針類成員指針**。
  • **不可**隱式轉換為整數類型 (`int`, `long` 等)。
  • `sizeof(nullptr) == sizeof(void*)`。
  • 可用於 `bool` 語境 (`if (ptr)` 等價 `if (ptr != nullptr)`)。

合法用法示例

int* p1 = nullptr;
char* p2 = nullptr;
void (*func)() = nullptr;
int MyClass::* mp = nullptr; // 成員指針

const char* str = "hello";
if (str != nullptr) std::cout << str; // 判空

// 模板推導
template void g(T* p);
g(nullptr); // T 推導為 void? 實際需顯式 g(nullptr) 或傳遞類型化 nullptr

非法用法 (編譯錯誤)

int i = nullptr;        // 錯誤:不能轉換為 int
if (nullptr) {}         // 錯誤:不能作為條件判斷 (需轉 bool? 實際可轉 bool,但標準規定不可直接用於 if 條件? 澄清:可隱式轉 bool,但建議寫 if (ptr) 或 if (ptr != nullptr))
nullptr = 0;            // 錯誤:不可賦值
void f(int); f(nullptr); // 錯誤:無法匹配 int 參數

最佳實踐

  1. 全面替代 NULL 和 0:所有指針初始化、賦值、比較、傳參均用 `nullptr`。
  2. 現代 C++ 風格:`int* p = nullptr;` 而非 `int* p = NULL;` 或 `int* p = 0;`。
  3. 智能指針:`std::unique_ptr p = nullptr;` / `std::shared_ptr p = nullptr;` 均正確。
  4. 模板代碼:用 `nullptr` 避免 `0` 被推導為 `int` 導致模板實例化錯誤。

對比表

表達式類型可隱式轉指針可隱式轉整數重載決議
`0``int`是 (C++ 允許 0 轉指針)是匹配 `int` 重載
`NULL``int` (C++) / `void*` (C)是是 (C++)匹配 `int` 重載 (C++)
`nullptr``std::nullptr_t`是否匹配指針重載

總結

`nullptr` 是 C++11 引入的**類型安全空指針字面量**,徹底解決 `NULL`/`0` 的重載決議歧義與類型安全問題。**現代 C++ 代碼中請無腦使用 `nullptr`**,拒絕 `NULL` 和 `0` 表示空指針。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved