C++中NULL與nullptr的區(qū)別對(duì)比
前言
在編寫C程序的時(shí)候只看到過(guò)NULL,而在C++的編程中,我們可以看到NULL和nullptr兩種關(guān)鍵字,其實(shí)nullptr是C++11版本中新加入的,它的出現(xiàn)是為了解決NULL表示空指針在C++中具有二義性的問(wèn)題,為了弄明白這個(gè)問(wèn)題,我查找了一些資料,總結(jié)如下。
一、C程序中的NULL
在C語(yǔ)言中,NULL通常被定義為:#define NULL ((void *)0)
所以說(shuō)NULL實(shí)際上是一個(gè)空指針,如果在C語(yǔ)言中寫入以下代碼,編譯是沒(méi)有問(wèn)題的,因?yàn)樵贑語(yǔ)言中把空指針賦給int和char指針的時(shí)候,發(fā)生了隱式類型轉(zhuǎn)換,把void指針轉(zhuǎn)換成了相應(yīng)類型的指針。
int *pi = NULL; char *pc = NULL;
二、C++程序中的NULL
但是問(wèn)題來(lái)了,以上代碼如果使用C++編譯器來(lái)編譯則是會(huì)出錯(cuò)的,因?yàn)镃++是強(qiáng)類型語(yǔ)言,void*是不能隱式轉(zhuǎn)換成其他類型的指針的,所以實(shí)際上編譯器提供的頭文件做了相應(yīng)的處理:
#ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif
可見(jiàn),在C++中,NULL實(shí)際上是0.因?yàn)镃++中不能把void*類型的指針隱式轉(zhuǎn)換成其他類型的指針,所以為了結(jié)果空指針的表示問(wèn)題,C++引入了0來(lái)表示空指針,這樣就有了上述代碼中的NULL宏定義。
但是實(shí)際上,用NULL代替0表示空指針在函數(shù)重載時(shí)會(huì)出現(xiàn)問(wèn)題,程序執(zhí)行的結(jié)果會(huì)與我們的想法不同,舉例如下:
#include <iostream> using namespace std; void func(void* i) { cout << "func1" << endl; } void func(int i) { cout << "func2" << endl; } void main(int argc,char* argv[]) { func(NULL); func(nullptr); getchar(); }
在這段代碼中,我們對(duì)函數(shù)func進(jìn)行可重載,參數(shù)分別是void*類型和int類型,但是運(yùn)行結(jié)果卻與我們使用NULL的初衷是相違背的,因?yàn)槲覀儽緛?lái)是想用NULL來(lái)代替空指針,但是在將NULL輸入到函數(shù)中時(shí),它卻選擇了int形參這個(gè)函數(shù)版本,所以是有問(wèn)題的,這就是用NULL代替空指針在C++程序中的二義性。
三、C++中的nullptr
為解決NULL代指空指針存在的二義性問(wèn)題,在C++11版本(2011年發(fā)布)中特意引入了nullptr這一新的關(guān)鍵字來(lái)代指空指針,從上面的例子中我們可以看到,使用nullptr作為實(shí)參,確實(shí)選擇了正確的以void*作為形參的函數(shù)版本。
總結(jié):
NULL在C++中就是0,這是因?yàn)樵贑++中void* 類型是不允許隱式轉(zhuǎn)換成其他類型的,所以之前C++中用0來(lái)代表空指針,但是在重載整形的情況下,會(huì)出現(xiàn)上述的問(wèn)題。所以,C++11加入了nullptr,可以保證在任何情況下都代表空指針,而不會(huì)出現(xiàn)上述的情況,因此,建議以后還是都用nullptr替代NULL吧,而NULL就當(dāng)做0使用。
其他:在沒(méi)有C++ 11的nullptr的時(shí)候,我們?cè)趺唇鉀Q避免這個(gè)問(wèn)題呢?
const class nullptr_t { public: template<class T> inline operator T*() const { return 0; } template<class C, class T> inline operator T C::*() const { return 0; } private: void operator&() const; } nullptr = {};
到此這篇關(guān)于C++中NULL與nullptr區(qū)別對(duì)比的文章就介紹到這了,更多相關(guān)C++ NULL與nullptr區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)線索二叉樹的定義與遍歷示例
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)線索二叉樹的定義與遍歷,結(jié)合具體實(shí)例形式分析了基于C語(yǔ)言的線索二叉樹定義及遍歷操作相關(guān)實(shí)現(xiàn)技巧與注意事項(xiàng),需要的朋友可以參考下2017-06-06C++11中內(nèi)聯(lián)函數(shù)(inline)用法實(shí)例
內(nèi)聯(lián)函數(shù)本質(zhì)還是一個(gè)函數(shù),但在聲明的時(shí)候,函數(shù)體要和聲明結(jié)合在一起,否則編譯器將它作為普通函數(shù)來(lái)對(duì)待,下面這篇文章主要給大家介紹了關(guān)于C++11中內(nèi)聯(lián)函數(shù)(inline)的相關(guān)資料,需要的朋友可以參考下2022-10-10C語(yǔ)言實(shí)現(xiàn)天氣信息管理系統(tǒng)
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)天氣信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06c++中?isupper()和islower()函數(shù)詳解
在C++中,islower()和isupper()是C++標(biāo)準(zhǔn)庫(kù)中提供的兩個(gè)字符判斷函數(shù),這兩個(gè)函數(shù)用于判斷一個(gè)字符是否為小寫字母或大寫字母,這篇文章主要介紹了c++?isupper()?islower()的相關(guān)資料,需要的朋友可以參考下2024-05-05C++、python和go語(yǔ)言實(shí)現(xiàn)的簡(jiǎn)單客戶端服務(wù)器代碼示例
這篇文章主要介紹了C++、python和go語(yǔ)言實(shí)現(xiàn)的簡(jiǎn)單客戶端服務(wù)器代碼示例,本文分別給出了3種語(yǔ)言的客戶端服務(wù)器通信代碼實(shí)例,需要的朋友可以參考下2015-03-03