欧美麻豆久久久久久中文_成年免费观看_男人天堂亚洲成人_中国一级片_动漫黄网站免费永久在线观看_国产精品自产av一区二区三区

中培偉業IT資訊頻道
您現在的位置:首頁 > IT資訊 > 軟件研發 > C ++中的nullptr到底是什么

C ++中的nullptr到底是什么

2020-07-21 13:52:40 | 來源:中培企業IT培訓網

對于有經驗的C ++和那些了解現代C ++編程語言的人來說,C ++中的nullptr到底是什么,這將是非常簡單的問題。但是nullptr不僅是C ++中的編程語言,而且為了解釋這一點,我們先了解一下NULL的問題,然后我們將深入研究nullptr的簡單實現以及nullptr的一些用例。為什么我們需要nullptr?區分整數0(零)(即NULL)和類型指針的實際null。

nullptr與NULL

NULL為0(零),即將C樣式類型轉換為void *的整數常數為零,而nullptr是nullptr_t類型的prvalue,該值是整數常量,其值為零。

對于那些相信NULL相同的人,即C和C ++中的(void *)0。想澄清的是,不是:

NULL-cppreference.com (C)

NULL-cppreference.com (C ++)

C ++要求將宏NULL定義為值為0的整數常量表達式。因此與C語言不同,在C ++標準庫中不能將NULL定義為(void *)0。

NULL問題

  1.隱式轉換

char *str = NULL; // Implicit conversion from void * to char *

int i = NULL; // OK, but `i` is not pointer type

  2.函數調用歧義

void func(int) {}

void func(int*){}

void func(bool){}

func(NULL); // Which one to call?

編譯會產生以下錯誤:

error: call to 'func' is ambiguous

func(NULL);

^~~~

note: candidate function void func(bool){}

^

note: candidate function void func(int*){}

^

note: candidate function void func(int){}

^

1error generated.

compiler exit status 1

3.構造函數重載

struct String

{

String(uint32_t) { /* size of string */ }

String(const char*) { /* string */ }

};

String s1( NULL );

String s2( 5 );

在這種情況下,需要顯式轉換(即String s((char *)0))。

  簡單的nullptr的實現

nullptr是“ 返回類型解析器” 慣用語的一個細微示例, 可以根據要為其分配實例的類型自動推斷出正確類型的空指針。

考慮以下最簡單且不復雜的nullptr實現:

struct nullptr_t

{

void operator&() const = delete; // Can't take address of nullptr

template

inline operator T*() const { return 0; }

template

inline operator T C::*() const { return 0; }

};

nullptr_t nullptr;

如果上面的代碼對您來說似乎很奇怪和怪異(盡管應該不會),那么我建議您閱讀我之前有關高級C ++概念的文章。這里的魔術只是模板化轉換運算符。

如果您有更權威的資料,那么這里是LLVM header中nullptr的具體實現。

nullptr的用例

struct C { void func(); };

int main(void)

{

int *ptr = nullptr; // OK

void (C::*method_ptr)() = nullptr; // OK

nullptr_t n1, n2;

n1 = n2;

//nullptr_t *null = &n1; // Address can't be taken.

}

如上例所示,當將nullptr分配給整數指針時,將創建模板化轉換函數的int類型實例,方法也是如此。

這樣,通過利用模板功能,實際上每次創建新類型分配時,我們實際上都在創建適當類型的空指針。

由于nullptr是值為零的整數文字,因此您無法使用通過刪除運算符完成的地址。

  1.函數使用nullptr調用清晰度

void func(int) { /* ... */}

void func(int *) { /* ... */}

void func(bool) { /* ... */}

func(nullptr);

現在,func(int *)將被調用,因為nullptr將隱式推導為int *。

  2.在nullptr_t上進行類型轉換

將nullptr_t強制轉換為整數類型需要reinterpret_cast,并且具有與(void *)0強制轉換為整數類型相同的語義。

只要目標類型足夠大,就將nullptr_t強制轉換為整數類型。考慮一下:

// int ptr_not_ok = reinterpret_cast(nullptr); // Not OK

long ptr_ok = reinterpret_cast(nullptr); // OK

reinterpret_cast無法將nullptr_t轉換為任何指針類型。請改用static_cast。

void func(int*) { /*...*/ }

void func(double*) { /*...*/ }

func(nullptr); // compilation error, ambiguous call!

// func(reinterpret_cast(nullptr)); // error: invalid cast from type 'std::nullptr_t' to type 'int*'

func(static_cast(nullptr)); // OK

nullptr可以隱式轉換為任何指針類型,因此使用static_cast進行顯式轉換僅有效。

  3.nullptr_t可比

int *ptr = nullptr;

if (ptr == 0); // OK

if (ptr <= nullptr); // OK

int a = 0;

if (a == nullptr); // error: invalid operands of types 'int' and 'std::nullptr_t' to binary 'operator=='

來自 Wikipedia:-…空指針常量:nullptr。它的類型為nullptr_t,它可以隱式轉換,并且可以與任何指針類型或指針到成員類型進行比較。

-除了布爾值,它不能隱式轉換或與整數類型媲美。

const int a = 0;

if (a == nullptr); // OK

const int b = 5;

if (b == nullptr); // error: invalid operands of types 'const int' and 'std::nullptr_t' to binary 'operator=='

  4.模板參數的類型為std :: nullptr_t

template

void ptr_func(T *t) {}

ptr_func(nullptr); // Can not deduce T

如前所述,Return Type Resolver需要一個受讓人來推斷類型。

template

void val_func(T t) {}

val_func(nullptr); // deduces T = nullptr_t

val_func((int*)nullptr); // deduces T = int*, prefer static_cast though

  5.從nullptr_t轉換為bool

從cppreference中:

-在直接初始化的上下文中 ,可以從std :: nullptr_t類型的prvalue初始化bool對象 ,包括nullptr。結果值為false。但是,這不被視為隱式轉換。

轉換僅允許直接初始化,而不允許復制初始化,其中包括按值將參數傳遞給函數的情況。例如:

bool b1 = nullptr; // Not OK

bool b2 {nullptr}; // OK

void func(bool){}

func(nullptr); // Not OK, need to do func(static_cast(nullptr));

6.雜項

typeid(nullptr); // OK

throw nullptr; // OK

char *ptr = expr ? nullptr : nullptr; // OK

// char *ptr1 = expr ? 0 : nullptr; // Not OK, types are not compatible

static_assert(sizeof(NULL) == sizeof(nullptr_t));

常見問題匯總

  何時引入nullptr?

C ++ 11

  nullptr是關鍵字還是std :: nullptr_t類型的實例?

true和false都是關鍵字和文字,因為它們都有一個類型(bool)。nullptr是類型為std :: nullptr_t 的指針文字,它是一個prvalue,即純 rvalue,您不能使用&來獲取它的地址更多。

  使用nullptr有什么優勢?

重載集之間沒有函數調用歧義。

您可以使用nullptr_t進行模板專業化。

代碼將變得更加安全,直觀和富有表現力。如果(ptr == nullptr); 而不是if(ptr == 0);。

  C ++中的NULL是否等于C ++ 11中的nullpt?

一點也不。以下行甚至無法編譯:

cout<<

  可以將nullptr轉換為bool嗎?

是,但僅當直接初始化時。即bool is_false {nullptr};。否則需要使用static_cast。

  如何定義nullptr?

它只是被稱為Return Type Resolver的模板化轉換運算符。

通過上述介紹,C ++中的nullptr到底是什么相信大家已經清楚了吧,如果想了解更多關于C ++的信息,請繼續關注中培偉業。

標簽: 軟件研發
主站蜘蛛池模板: 成人看片黄A免费看那个网址 | 精品少妇人妻AV无码久久 | 宅女午夜福利免费视频 | 777777777妇女亚洲 | 无码Aⅴ在线观看 | 亚洲AV无码一区二区三区系列 | 无尽动漫性视频╳╳╳3d | 免费观看羞羞视频网站 | 免费无码又爽又刺激高潮 | 无码帝国www无码专区色综合 | 日韩视频精品在线观看 | 亚洲中文字幕无码一久久区 | 日本在线观看 | 国产gaysexchain男同men高清 | 男女一级毛片 | 欧美人与动性行为视频 | 日本熟妇XXX50 | 国产乡下三级全黄三级 | 激情综合五月开心婷婷 | 嫩草影业地址 | 天堂素人约啪 | 久久午夜夜伦鲁鲁片免费无码 | 早起邻居人妻奶罩太松av | 日产乱码一二三区别免费麻豆 | 黑人上司好猛我好爽中文字幕 | 国精产品一码一码三MBA | 日韩精品在线网站 | 小14萝裸体洗澡视频免费网站 | 午夜在线观看免费线无码视频 | 在线播放国产精品三级 | 乌克兰性欧美精品高清 | 亚洲AV午夜成人片 | 欧美综合精品久久久久成人影院 | 麻豆视频www| 铜铜铜铜铜铜铜铜好大无打码 | 巜被社长侵犯的人2中文在线 | 亚洲一区二区三区中文字幕无码 | 国产丝袜一区视频在线观看 | 99久久久国产精品消防器材 | 亚洲成a人片在线不卡一二三区 | 人人藻人人澡人人爽 |