c++11中的noexcept關(guān)鍵字
c++11中noexcept關(guān)鍵字
1. 概念
noexcept關(guān)鍵字是c++11之后新增的。該關(guān)鍵字會(huì)告訴編譯器,被修飾的函數(shù)不會(huì)發(fā)生異常,這有利于編譯器對(duì)程序做更多的優(yōu)化。
2. 兩種形式
1)noexcept
2)noexcept(expression)
noexcept(true) 表示被修飾的函數(shù)不拋出異常,noexcept(false) 表示被修飾的函數(shù)會(huì)拋出異常。
3. 異常處理
//例1 bool Compare(int x, int y) throw() ? //C++11之前 { ?? ?return x > y; } ? //例2 bool Compare(int x, int y) noexcept(noexcept(x > y)) ?//C++11 { ?? ?return x > y; }
例2用到了noexcept運(yùn)算符,表示,如果x > y不發(fā)生異常,則Compare函數(shù)不會(huì)發(fā)生異常。
4. 實(shí)現(xiàn)原理
noexecpt函數(shù)向外拋出了異常(如果函數(shù)內(nèi)部捕捉了異常并完成處理,這種情況不算拋出異常),程序會(huì)直接終止,調(diào)用std::terminate()函數(shù),該函數(shù)內(nèi)部會(huì)調(diào)用std::abort()終止程序。
5. 使用場(chǎng)景
1)移動(dòng)構(gòu)造函數(shù)
2)移動(dòng)分配函數(shù)
3)析構(gòu)函數(shù)
4)葉子函數(shù)
c++11關(guān)鍵字noexcept替代throw
相比于斷言適用于排除邏輯上不可能存在的狀態(tài),異常通常是用于邏輯上可能發(fā)生的錯(cuò)誤。
在異常處理的代碼中,程序員有可能看到過(guò)如下的異常聲明表達(dá)形式:
void excpt_func() throw(int, double) { ... }
在excpt_func函數(shù)聲明之后,我們定義了一個(gè)動(dòng)態(tài)異常聲明throw(int, double),該聲明指出了excpt_func可能拋出的異常的類(lèi)型。事實(shí)上,該特性很少被使用,因此在C++11中被棄用了(參見(jiàn)附錄B),而表示函數(shù)不會(huì)拋出異常的動(dòng)態(tài)異常聲明throw()也被新的noexcept異常聲明所取代。
noexcept形如其名地,表示其修飾的函數(shù)不會(huì)拋出異常。不過(guò)與throw()動(dòng)態(tài)異常聲明不同的是,在C++11中如果noexcept修飾的函數(shù)拋出了異常,編譯器可以選擇直接調(diào)用std::terminate()函數(shù)來(lái)終止程序的運(yùn)行,這比基于異常機(jī)制的throw()在效率上會(huì)高一些。這是因?yàn)楫惓C(jī)制會(huì)帶來(lái)一些額外開(kāi)銷(xiāo),比如函數(shù)拋出異常,會(huì)導(dǎo)致函數(shù)棧被依次地展開(kāi)(unwind),并依幀調(diào)用在本幀中已構(gòu)造的自動(dòng)變量的析構(gòu)函數(shù)等。
noexcept修飾符有兩種形式
- 一種就是簡(jiǎn)單地在函數(shù)聲明后加上noexcept關(guān)鍵字。比如:void excpt_func() noexcept;
- 另外一種則可以接受一個(gè)常量表達(dá)式作為參數(shù),如下所示:void excpt_func() noexcept (常量表達(dá)式);
常量表達(dá)式的結(jié)果會(huì)被轉(zhuǎn)換成一個(gè)bool類(lèi)型的值。該值為true,表示函數(shù)不會(huì)拋出異常,反之,則有可能拋出異常。這里,不帶常量表達(dá)式的noexcept相當(dāng)于聲明了noexcept(true),即不會(huì)拋出異常。
在C++98中,new可能會(huì)包含一些拋出的std::bad_alloc異常。
void* operator new(std::size_t) throw(std::bad_alloc); ? void* operator new[](std::size_t) throw(std::bad_alloc); ?
而在C++11中,則使用noexcept(false)來(lái)進(jìn)行替代。
void* operator new(std::size_t) noexcept(false); void* operator new[](std::size_t) noexcept(false); ?
當(dāng)然,noexcept更大的作用是保證應(yīng)用程序的安全。比如一個(gè)類(lèi)析構(gòu)函數(shù)不應(yīng)該拋出異常,那么對(duì)于常被析構(gòu)函數(shù)調(diào)用的delete函數(shù)來(lái)說(shuō),C++11默認(rèn)將delete函數(shù)設(shè)置成noexcept,就可以提高應(yīng)用程序的安全性。
void operator delete(void*) noexcept; void operator delete[](void*) noexcept; ?
而同樣出于安全考慮,C++11標(biāo)準(zhǔn)中讓類(lèi)的析構(gòu)函數(shù)默認(rèn)也是noexcept(true)的
另外:
void fun (); // 能拋出任何類(lèi)型的異常 void fun () throw(except1,except2,except3) // 后面括號(hào)里面是一個(gè)異常參數(shù)表,本例中只能拋出這3中異常 void fun () throw() ? // 參數(shù)表為空,不能拋出異常
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C++基于easyx圖形庫(kù)實(shí)現(xiàn)打磚塊游戲
這篇文章主要為大家詳細(xì)介紹了C++基于easyx圖形庫(kù)實(shí)現(xiàn)打磚塊游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05C++實(shí)現(xiàn)簡(jiǎn)易反彈小球游戲的示例代碼
我們利用printf 函數(shù)實(shí)現(xiàn)一個(gè)在屏幕上彈跳的小球。彈跳的小球游戲比較簡(jiǎn)單、容易入門(mén),也是反彈球消磚塊、接金幣、臺(tái)球等很多游戲的基礎(chǔ),感興趣的可以了解一下2022-10-10C語(yǔ)言的fork函數(shù)在Linux中的進(jìn)程操作及相關(guān)面試題講解
fork函數(shù)只能在類(lèi)Unix的系統(tǒng)中使用,用于創(chuàng)建子線程,這里總結(jié)了C語(yǔ)言的fork函數(shù)在Linux中的進(jìn)程操作及相關(guān)面試題講解,先來(lái)看一下C語(yǔ)言程序的存儲(chǔ)空間與進(jìn)程示意:2016-06-06C語(yǔ)言獲取Linux系統(tǒng)精確時(shí)間的方法
下面小編就為大家?guī)?lái)一篇C語(yǔ)言獲取Linux系統(tǒng)精確時(shí)間的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09C語(yǔ)言約瑟夫環(huán)的實(shí)現(xiàn)
這篇文章主要介紹了C語(yǔ)言約瑟夫環(huán)的實(shí)現(xiàn)的相關(guān)資料,這里主要是利用數(shù)據(jù)數(shù)據(jù)結(jié)果中循環(huán)鏈表來(lái)實(shí)現(xiàn),需要的朋友可以參考下2017-08-08