姓名:雷瀟 16030110083
轉載自:http://www.lai18.com/content/24569586.html
【嵌牛導讀】這是C++11新特性介紹的第一部分,比較簡單易懂,但是也有一些有趣的地方。
不想看toy code的讀者可以直接拉到文章最后看這部分的總結。
【嵌牛鼻子】數據類型的定義,指針
【嵌牛提問】如何選取適當的數據類型才能滿足存儲的要求?
【嵌牛正文】
新類型
long long類型
C++11標準中新加入了long long類型屬性,占用空間不小于long類型。測試代碼如下:
[cpp]view plaincopy
longlarge?=?LONG_MAX;
longlonglong_large?=?LLONG_MAX;
longlonglong_long_large?=?1LL?<<?63;
cout<<"test?long?long:"<
在我的機器上實測,long long類型和long類型同樣使用64bit空間。
nullptr字面量
C++11標準中專門為空指針增加了nullptr字面量,同時不推薦再使用NULL或者0表示空指針。
[cpp]view plaincopy
int*p1?=?nullptr;
int*p2?=?0;
int*p3?=?NULL;
cout<<"test?nullptr:?"<<(p1?==?p2)<<'\t'<<(p1?==?p3)<
最終測試結果,nullptr和NULL和0是一樣的。
constexpr
C++11標準中新增constexpr用于聲明常量表達式,編譯器會驗證此變量的值是否是一個常量表達式。
[cpp]view plaincopy
intout_i?=?0;//?out_i定義于函數外部
...
constexprintmf?=?20;
constexprintlimit?=?mf?+?1;
constexprint*p4?=?&out_i;
//?the?following?would?cause?a?make?error
//?since?large?is?not?a?constexpr
//constexpr?int?wrong?=?large?+?1;
//?since?&in_j?is?not?a?constexpr;
//int?in_j?=?0;
//constexpr?int?*p5?=?&in_j;
值得注意的是,constexpr指針可以指向非常量變量,只要此變量定義于函數之外,因為這樣的變量的指針(地址)是可以在編譯期確定的。
另外,下面的constexpr指針與const指針的含義是完全不同的:
[cpp]view plaincopy
constexprint*p6?=?nullptr;//?a?const?pointer?point?to?an?int
//?p6?=?&out_i;?//?error:?p6?is?a?constexpr
constint*p7?=?nullptr;//?a?pointer?point?to?a?const?int
第一個指針表示一個常量指針,即指針的值是常量;而第二個指針表示一個指向const int的指針,即指針指向的值是常量。
constexpr還可以用于函數,constexpr函數是指能用于常量表達式的函數,它遵循以下幾條約定:
a.返回類型是字面值類型
b.形參類型是字面值類型
c.函數體中必須有且僅有一條return語句
[cpp]view plaincopy
constexprintsz()?{return42;?}
constexprintnew_sz(intcnt)?{returnsz()?*?cnt;?}
constexprintsize?=?sz();
constexprintnsize?=?new_sz(mf);
//constexpr?int?wrong_size?=?new_sz(out_i);?//?error:?out_i?is?not?a?constexpr
cout<<"test?constexpr:?"<
noexcept
noexcept可以用作異常指示符,用于指示一個函數是否會拋出異常。編譯器并不檢查使用了noexcept的函數是否真的不拋出異常,在運行時,如果一個使用noexcept承諾不拋出異常的函數實際拋出了異常,那么程序會直接終止。
[cpp]view plaincopy
voidno_except()?noexcept
{
throw1;
}
//?the?following?call?will?cause?terminate
//no_except();
noexcept還可以帶參數,noexcept(true)表示不會拋出異常,noexcept(false)表示可能拋出異常。
同時noexcept還可以用作運算符,接受一個函數調用,返回一個bool值表示是否會拋出異常。noexcept運算符并不會對其實參進行求值。
將noexcept運算符,結合帶參數的noexcept指示符,可以得到如下常用法:
[cpp]view plaincopy
voidno_except2()?noexcept(noexcept(no_except())){}
cout<<"test?noexcept:?"<
這種用法表示no_except2和no_except的異常說明保持一致。
初始化
列表初始化
C++11新標準中為很多類型增加了列表初始化的功能。
可以用列表初始化一個簡單變量。
[cpp]view plaincopy
intsingle_int1?=?0;
intsingle_int2?=?{0};
cout<<"test?list?initialization:\n"<
可以用列表初始化一個容器(vector,list,map,set…)。
[cpp]view plaincopy
//?vector/list?list?initialization
vector?v1?=?{"ab","cd","ef"};
list?l2{"gh","ij","kl"};
//vector?v3("mn",?"op",?"qr");?//?wrong?initialization?format
cout<<"test?vector/list?list?initialization:\n"<
//?map/set?list?initialization
map?m1?=
{
{"a","A"},
{"b","B"},
{"c","C"}
};
m1.insert({"d","D"});
set?s1?=?{"a","b","c"};
cout<<"test?map/set?list?initialization:\n"<
可以在使用new動態分配內存時使用列表初始化。
[cpp]view plaincopy
vector?*pv?=newvector{0,?1,?2,?3,?4};
int*pi?=newint[5]{0,?1,?2,?3,?4};
cout<<"test?new?alloator?using?list?initialization:\n"<<(*pv)[2]<<'\t'<
可以在傳入參數/函數返回值時使用列表初始化。
[cpp]view plaincopy
m1.insert({"d","D"});
vector?error_msg(inttyp)
{
switch(typ)
{
case1:
return{"type1","msg1"};
case2:
return{"type2","msg2"};
default:
return{};
}
}
pair?get_pair(inttyp)
{
if(typ?==?1)return{"key","value"};
returnpair("default?key","default?value");
}
vector?err_msg1?=?error_msg(1);
vector?err_msg2?=?error_msg(2);
vector?err_msg3?=?error_msg(3);
cout<<"test?return?value?list?initialization:\n"<
pair?p1?=?get_pair(1);
pair?p2?=?get_pair(2);
cout<<"test?return?pair?list?initialization:\n"<
類內成員初始化
C++11標準中允許直接對類內成員進行初始化/列表初始化。
[cpp]view plaincopy
classInitClass
{
public:
voidprint_class()
{
cout<
}
private:
intfield1?=?1;
intfield2;
doublefield3?=?1.0;
doublefield4;
};
classInitClassMgr
{
public:
vector?init_objs?=?{InitClass()};
};
InitClass?test_class;
cout<<"test?class?member?initialization:\n";
test_class.print_class();
InitClassMgr?mgr;
cout<<"test?class?member?of?class?type?initialization:\n";
mgr.init_objs[0].print_class();
總結
long long類型。
nullptr字面量用于表示空指針。
constexpr用于表示常量表達式。
noexcept可以用于指示一個函數是否會拋出異常,同時可以用作運算符判定一個函數是否承諾不拋出異常。
新增基礎類型、容器類型、new分配內存時的列表初始化。構建臨時變量時也可以直接使用列表初始化。
可以直接對類內成員進行初始化/列表初始化。