簡介,C++98/03 關鍵字,關鍵字的改變,C++11詳解,alignas,constexpr,char16_t 和 char32_t,decltype,nullptr,noexcept,static_assert,auto,其它詳解,asm,auto,*_cast,bool,true,false,break,continue,goto,case,default,switch,catch,throw,try,char,wchar_t,const,volatile,struct,class,union,delete,new,do,for,while,數值類型,if,else,enum,explicit,export,extern,friend,inline,mutable,namespace,operator,private,protected,public,register,return,static,sizeof,template,this,typedef,virtual,typeid,typename,using,void,try,
簡介
各個版本的
ISO C++都規定以下劃線接大寫字母或下劃線起始的標識符保留給實現,
編譯器可以用這些保留標識符作為擴展關鍵字,這不保證可移植性。
C++98/03 關鍵字
ISO C++98/03關鍵字共63個,此處嚴格按標準原文排版:
asm
| do
| if
| return
| typedef
|
auto
| double
| inline
| short
| typeid
|
bool
| dynamic_cast
| int
| signed
| typename
|
break
| else
| long
| sizeof
| union
|
case
| enum
| mutable
| static
| unsigned
|
catch
| explicit
| namespace
| static_cast
| using
|
char
| export
| new
| struct
| virtual
|
class
| extern
| operator
| switch
| void
|
const
| false
| private
| template
| volatile
|
const_cast
| float
| protected
| this
| wchar_t
|
continue
| for
| public
| throw
| while
|
default
| friend
| register
| true
| |
delete
| goto
| reinterpret_cast
| try
| |
關鍵字的改變
新增關鍵字:alignas、alignof、char16_t、char32_t、constexpr、decltype、noexcept、nullptr、static_assert、thread_local。
auto 的意義改變。
register 被視為過時的(可能在未來標準移除)。
export 因為實現支持太少(僅Edison Design Group的前端支持),編譯效率低下,取消原有意義(仍是關鍵字,但使用它的程式是錯誤的),改為保留給未來標準使用。
C++11詳解
alignas
alignof用於獲取取指定表達式指定的(類似sizeof,可以直接是類型名)的對齊(alignment)。alignas用於聲明時指定對齊類似於現有的類型。和sizeof類似,兩者的運算元都不被求值。
constexpr
類似const但更強大,修飾函式或對象,表示函式結果或對象是編譯時決定的常量,以便最佳化。(const不能修飾一般的函式,也不一定指定聲明的對象能編譯期的常量表達式,更可能只是唯讀對象。而在C語言中,const完全只能指定唯讀對象。)
char16_t 和 char32_t
二者分別表示16位字元型和32位字元型,類似char和wchar_t,也是一般只專用於表示字元的整數類型,且設計上用於表示
Unicode字元。char16_t和char32_t是C++11新增的,以克服wchar_t在不同平台上無法保證確定寬度的缺點。
decltype
用於編譯時推斷類型。此外參與函式聲明的另一種語法:指定返回auto,同時decltype引導trailing-return-type指定實際應該返回類型。decltype的運算元也不被求值。
nullptr
字面量nullptr是具有std::nullptr_t類型的右值,是空指針常量。C++98/03中表示空指針常量的NULL或0都會在重載中引起混淆,而純庫的解決方案在這裡也遇到困難,所以有必要加入新的關鍵字來專門表示空指針。
noexcept
實踐表明動態異常規範會影響運行時性能。新增的noexcept表示靜態異常規範,只指定函式(模版)是否有異常拋出,這裡noexcept即noexcept(true),表示沒有異常拋出。除了異常規範,noexcept可以作用於一個表達式來判斷是否有異常,這對於模版代碼非常有用。
static_assert
用於編譯時的靜態斷言:若指定的表達式為false則編譯失敗。
auto
C++11標準和C++98/03標準的auto是不同的。C++98/03標準中,auto表示自動儲存類型;C++11標準中,auto表示由編譯器靜態判斷其應有的類型。
其它詳解
asm
用於語法:
asm-definition:
asm ( string-literal ) ;
意義由實現定義,典型實現中傳輸其中的字元串給
彙編器。
auto
在C++98/03中這個這個關鍵字用於聲明塊中的變數的生存期為自動生存期,若是對象同時具有自動存儲類,即生存期在塊結束時結束。這樣的變數被稱為
局部變數。這個關鍵字不常用,因為即便省略,聲明的默認就是auto的。
在C++11中,auto的含義改變為自動通過初值符推斷聲明的類型占位符。如聲明auto i = 1;,auto就相當於int,因為1是int類型,可以推斷出i的類型。也可以使用auto& i等聲明,具體推導規則同模版參數類型推導。
*_cast
即const_cast、dynamic_cast、reinterpret_cast、static_cast。
C++風格的類型轉換。dynamic_cast是動態的,需要運行時支持;其它都是靜態檢查,相比C風格的類型轉換更加細化,增強了類型安全性。
bool,true,false
bool即
布爾類型,屬於基本類型中的整數類型,取值為真和假。true和false是具有bool類型的
字面量,是
右值,分別表示真和假。
break,continue,goto
break用於跳出for或while循環或switch。continue用於跳轉到循環起始。goto用於無條件跳轉到函式內的標號。
結構化程式較少使用goto,更多使用循環代替。
case,default,switch
switch分支語句的起始,根據switch條件跳轉到case標號或defalut標記的分支上。
catch,throw,try
用於
異常處理。try指定try塊的起始,try塊後的catch可以捕獲異常。異常由throw拋出。throw在函式中還表示動態異常規範,但在C++11中被標記為過時(由noexcept部分取代)。
char,wchar_t
表示
字元型和寬字元型這些整數類型(屬於基本類型),但一般只專用於表示字元。char(和signed char、unsigned char一起)事實上定義了位元組的大小。
const,volatile
const和volatile是類型修飾符,語法類似,在C++中合稱為cv-限定符(cv-qualifier)。可以共同使用。用於變數或函式參數聲明,也可以限制非靜態成員函式。const表示唯讀類型(指定類型安全性,保護對象不被意外修改),volatile指定被修飾的對象類型的讀操作是副作用(因此讀取不能被隨便最佳化合併,適合映射I/O暫存器等)。
struct,class,union
用於類型聲明。class是一般的類類型。struct在C++中是特殊的類類型,聲明中僅默認
隱式的成員和基類訪問限定與class不同(struct是public,class是private)。union是聯合體類型。滿足特定條件類類型——POD struct或POD union可以和
C語言中的struct和union對應兼容。
class還有個用途是在模版類型聲明中作為表示模版類型參數或模版模版參數的語法的必要組成部分。前者也可被typename代替。
delete,new
delete單獨使用,表示釋放具有
動態存儲期對象,默認版本調用全局的去配器(deallocator)::operator delete和析構函式。new單獨使用,表示請求分配動態存儲期對象,默認版本調用全局的分配器(allocator)::operator new和指定的析構函式。和operator連用表示分別表示去配器(operator delete)和分配器(operator new),用於釋放分配器(allocator)的記憶體和分配記憶體。operator delete也在分配記憶體被異常中斷時被調用。
do,for,while
循環語句的組成部分。C++支持do-while循環、for循環和while循環。C++11新增了ranged-based for循環,用:分隔聲明的對象和指定循環的範圍。
數值類型
即double、float、long、int、short、signed、unsigned。
signed和unsigned作為
前綴修飾整數類型,分別表示有符號和無符號。signed和unsigned修飾char類型,構成unsigned char和signed char,和char都不是相同的類型;不可修飾wchar_t、char16_t和char32_t。其它整數類型的signed省略或不省略,含義不變。signed或unsigned可單獨作為類型,相當於signed int和unsigned int。
double和float專用於浮點數,double表示雙精度,精度不小於float表示的浮點數。long double則是C++11指定的精度不小於double的浮點數。
其它關鍵字表示整數類型。從占用空間大小(sizeof)來看,保證char<=short<=int<=long<=long long。注意這些都不是相同的類型,即便大小和範圍都一致;各自具有unsigned版本。其中long long是C++11指定的不小於long的整數。
if,else
條件語句的組成部分。if表示條件,之後else表示否定分支。
enum
構成枚舉類型名的關鍵字。C++11新增帶作用域的枚舉,用enum class或enum struct(兩者等價)聲明。
explicit
C++11從兩個角度擴展了用法。其一是適用於
轉換函式(模版),類似構造函式,避免不需要的重載。其二是列表初始化,除非直接使用std::initializer_list,顯式構造函式被列表初始化忽略(在C++98/03中,explicit僅對單一參數調用構造函式有意義,這裡打破了這個限制)。
export
導出模版,用於分離編譯。當初標準委員會未經充分實踐支持匆忙通過了這一決定,被EDG證明具備不現實的可用性(即便EDG唯一地實現了這一個特性,他們也表示反對)。MSVC、GCC、Clang等其它主流編譯器前端都沒有實現這一特性,甚至這是唯一明顯約定不符合C++98/03的特性。C++11廢除了這個
export關鍵字的含義,但保留這個關鍵字,供以後使用。
extern
extern意為“外來的”,是存儲類聲明修飾符。這個關鍵字在C語言中即很不明確,容易被混淆(尤其是extern inline——好在C++沒有這種用法)。extern表示被修飾的聲明中,名稱的連結保持和之前的一致(若已有相同聲明存在),或保持默認值(若之前沒有相同名稱的聲明存在)——取決於聲明的位置。在命名空間作用域(注意包括全局命名空間),extern表示外部連結;若這裡省略extern,則對於const對象,默認具有內部連結;否則表示具有和命名空間一致的連結(若頂層沒有嵌套未命名的命名空間,就是外部連結,否則是內部連結)。
C++11新增extern用於模版顯式實例化聲明,表示不在當前翻譯單元實例化模版,而在別處有定義。這可以提升編譯效率。
friend
inline
聲明定義
內聯函式(模版),提示編譯時內聯——將所調用的代碼嵌入到主調函式中。注意是否內聯取決於實現——編譯器有權不實際內聯,如果它認為這是必要的或更符合預期的目標代碼質量。但inline還改變了ODR(One Definition Rule)的適用性。類似函式模版,在頭檔案直接定義inline函式不會視為重複定義違反ODR而編譯出錯。C++中,一個函式若聲明inline,則每處聲明都必須保證是inline,和C語言允許extern inline或static inline不同——儘管C++實現可以提供類似非標準的擴展。注意類成員函式若在類定義內給出定義則隱含inline。
C++11中,新增inline namespace,指示命名空間中的名稱同時是外層命名空間直接包含的名稱。這便於命名空間的版本管理,減少衝突。
mutable
用於類的非靜態非const數據成員,表示不受到成員函式的const的限制,可以在const成員函式中使用。
namespace
表示命名空間——其中可以聲明若干標識符,組成的名稱與其它命名空間不衝突。
可以聲明一個命名空間或命名空間別名。
operator
和操作符連用,指定一個重載了的操作符函式,也包括operator new和operator delete。
private,protected,public
指定類成員或基類中的名稱的訪問許可權控制,分別表示僅供本類使用、供本類和派生類使用、不設限制。
register
提示聲明的對象被放入暫存器中以便得到更好的性能。同inline類似,並非強制;不同的是這個提示經常被現代的編譯器無視,因此C++11中被標記為過時的。
return
子程式返回語句,終止當前函式執行,使
控制流返回到主調函式的調用後。若返回類型不是void可以同時帶返回值。
static
和
C語言類似,聲明靜態存儲期對象,或指定一個函式的名稱具有
內部連結。在C++還有另一個用途——用於類作用域聲明,表示聲明的成員是類共有的,不需要通過類的對象訪問。類的靜態數據成員也具有靜態存儲期,除非被thread_local修飾。
sizeof
返回類型名或表達式具有的類型對應的大小。不能對函式使用(雖然可能有非標準擴展)。C++11新增支持直接對類的數據成員作為運算元(之前無法使用)。sizeof的運算元是不被求值的,利用這一點可以配合模版元編程測試類型正確性。
template
聲明一個模板、模版的特化或顯式實例化(另見extern)。模版用於打破類型系統的某些限制,推遲類型檢查到實例化得到具體的模版實例進行以復用代碼,實現泛型和參數化編程。
this
this是一種實體,僅在類的非靜態成員中使用,是指向類的對象的指針右值。
typedef
用以給數據類型取別名。字面名義上是定義,實際只是聲明——這點和C語言的說法不同。
C++11中可被using新增的用法代替。
virtual
聲明
虛基類或
虛函式。具有虛基類或虛函式的類是多態類(polymorphic class),需要運行時提供支持來判斷成員函式調用分派到的具體類型。
typeid
獲取表達式的類型,以std::type_info表示結果,可能拋出std::bad_typeid。當運算元非多態類(引用)類型在編譯時即可確定結果,否則需要在運行時取得結果,即
RTTI。
typename
告訴編譯器一個嵌套的限定名(包含::)中的未知的標識符是一個類型。這只在模板中需要區分依賴名稱時使用。
另一種用法是在模版聲明參數列表中表示模版類型參數,可被
class代替。
using
有兩種基本用法:using
聲明和using
指示(using namespace ...)。
前者是聲明,引入命名空間或基類作用域內已經被聲明的名稱。後者引入命名空間內所有的名稱。
C++11新增了一類用法,可以代替typename,同時可以配合template使用(typedef基於語法考慮未被允許加入這種用法)。
void
特殊的“空”類型,指定函式無返回值或無參數(在參數列表中只能夠唯一地使用),用於表達式轉換為void類型以丟棄計算值的必要(C++11加入了discarded-value-expression顯式地指出了這一點),或用於void*
指針類型。
try
try,C++中用於異常處理的組合。