C/C++ 歷史上用 `NULL` (宏) 或 `0` 表示空指針,但存在**類型安全缺陷**:
#includevoid 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*)
int* p1 = nullptr; char* p2 = nullptr; void (*func)() = nullptr; int MyClass::* mp = nullptr; // 成員指針 const char* str = "hello"; if (str != nullptr) std::cout << str; // 判空 // 模板推導 templatevoid 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 參數
| 表達式 | 類型 | 可隱式轉指針 | 可隱式轉整數 | 重載決議 |
|---|---|---|---|---|
| `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` 表示空指針。