空指针:从 0 到 NULL,再到 nullptr
生活随笔
收集整理的這篇文章主要介紹了
空指针:从 0 到 NULL,再到 nullptr
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
nullptr
空指針:從 0 到 NULL,再到 nullptr
NULL 是一個宏定義:
#undef NULL #if defined(__cplusplus) #define NULL 0 #else #define NULL ((void *)0) #endif?
int *my_ptr = 0; int *my_ptr = NULL; // NULL 的問題 #include <stdio.h>void f(char *c) {printf("invoke f(char *)\n); } void f(int i) {printf("invoke f(int)\n"); } int main() {f(0);f(NULL); // 注意:如果gcc編譯,NULL會轉換為內部標識符 __null,該語句會編譯失敗f((char*)0); } /** 使用 XLC 編譯器會得到如下結果:* invoke f(int)* invoke f(int)* invoke f(char*)* XLC 將 NULL 定義為了 0 */引起該問題的原因是 0 的二義性。0 既可以表示整型,也可以表示一個 空指針(void *)。存在二義性時,需要使用強制類型轉換:((void *)0).
雖然 g++ 編譯器將 NULL 轉換為編譯器內部標識符(__null),并在編譯時期進行了分析,在一定程度上可以緩解問題,但是會帶來代碼移植的限制。
?
nullptr
// 頭文件: cstddef typedef decltype(nullptr) nullptr_t; /*使用 nullptr_t 必須包含頭文件: cstddef。使用 nullptr 則不需要 */nullptr 最大的優勢是 有類型,且可以被隱式轉換為指針類型。
#include <stdio.h>void f(char *c) {printf("invoke f(char *)\n); } void f(int i) {printf("invoke f(int)\n"); } int main() {f(nullptr); // invoke f(char *)f(0); // invoke f(int) }nullptr 和 nullptr_t
C++11 不僅定義了空指針常量 nullptr,也定義了 空指針類型 nullptr_t。那么也就是說 nullptr_t 可以用來定義變量。通常,可以使用 nullptr_t 聲明一個 空指針變量。
- C++11規定:
- 所有定義為 nullptr_t 類型的數據都是等價的,行為也是完全一致。
- nullptr_t 類型數據可以隱式轉換為任意一個指針類型。
- nullptr_t 類型數據不能轉化為 非指針類型,即使使用 reinterpret_cast<nullptr_t>()。
- nullptr_t 類型數據不適用于算術運算表達式。
- nullptr_t 類型數據可以用于關系運算表達式,但僅能與 nullptr_t 類型數據或指針類型數據做比較,當且僅當關系運算符為 ==, <=, >=時返回 true.
雖然 nullptr_t 看起來像是一個 指針類型,但是在把 nullptr_t 應用于模板時,我們發現模板卻只能把他作為一個普通的類型來推導。(并不會將其視為 T* 指針)
using namespace std; template<typename T> void g(T* t) {} template<typename T> void h(T t) {}int main() {g(nullptr); // error,nullptr 時 nullptr_t 類型,而不是指針g((float*)nullptr); // T = floath(0); // T = inth(nullptr); // T = nullptr_th((float*)nullptr); // T = float *}一些關于 nullptr 規則的討論
-
sizeof(nullptr_t) == sizeof(void *)
-
nullptr 是一個編譯時期的常量,它的名字是一個編譯時期的關鍵字,能夠為編譯器識別。
-
(void *)0 只是一個強制轉換表達式,其返回的也是一個 void * 指針類型
-
nullptr 到任何指針的轉換都是隱式的。
-
nullptr 對象的地址可以被用戶使用
?
總結
以上是生活随笔為你收集整理的空指针:从 0 到 NULL,再到 nullptr的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为一个优秀的C++程序员
- 下一篇: c __cplusplus详解