C++11新特性之新类型与初始化
C++11新特性之新類型與初始化
snoone | 2016-06-23 11:57 ?? 瀏覽量(148) ?? 評(píng)論(0) ??推薦(0) 數(shù)據(jù)這是C++11新特性介紹的第一部分,比較簡(jiǎn)單易懂,但是也有一些有趣的地方。
不想看toy code的讀者可以直接拉到文章最后看這部分的總結(jié)。
新類型
long long類型
C++11標(biāo)準(zhǔn)中新加入了long long類型屬性,占用空間不小于long類型。測(cè)試代碼如下:
| 1 2 3 4 | long?large?=?LONG_MAX; long?long?long_large?=?LLONG_MAX; long?long?long_long_large?=?1LL?<<?63; cout<<"test?long?long:"<<large<<'\t'<<long_large<<'\t'<<long_long_large<<endl; |
在我的機(jī)器上實(shí)測(cè),long long類型和long類型同樣使用64bit空間。
nullptr字面量
C++11標(biāo)準(zhǔn)中專門為空指針增加了nullptr字面量,同時(shí)不推薦再使用NULL或者0表示空指針。
| 1 2 3 4 | int?*p1?=?nullptr; int?*p2?=?0; int?*p3?=?NULL; cout<<"test?nullptr:?"<<(p1?==?p2)<<'\t'<<(p1?==?p3)<<endl; |
最終測(cè)試結(jié)果,nullptr和NULL和0是一樣的。
constexpr
C++11標(biāo)準(zhǔn)中新增constexpr用于聲明常量表達(dá)式,編譯器會(huì)驗(yàn)證此變量的值是否是一個(gè)常量表達(dá)式。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | int?out_i?=?0;?//?out_i定義于函數(shù)外部 ... constexpr?int?mf?=?20; constexpr?int?limit?=?mf?+?1; constexpr?int?*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指針可以指向非常量變量,只要此變量定義于函數(shù)之外,因?yàn)檫@樣的變量的指針(地址)是可以在編譯期確定的。
另外,下面的constexpr指針與const指針的含義是完全不同的:
| 1 2 3 | constexpr?int?*p6?=?nullptr;?//?a?const?pointer?point?to?an?int //?p6?=?&out_i;?//?error:?p6?is?a?constexpr const?int?*p7?=?nullptr;?//?a?pointer?point?to?a?const?int |
第一個(gè)指針表示一個(gè)常量指針,即指針的值是常量;而第二個(gè)指針表示一個(gè)指向const int的指針,即指針指向的值是常量。
constexpr還可以用于函數(shù),constexpr函數(shù)是指能用于常量表達(dá)式的函數(shù),它遵循以下幾條約定:
a.返回類型是字面值類型
b.形參類型是字面值類型
c.函數(shù)體中必須有且僅有一條return語(yǔ)句
| 1 2 3 4 5 6 | constexpr?int?sz()?{?return?42;?} constexpr?int?new_sz(int?cnt)?{?return?sz()?*?cnt;?} constexpr?int?size?=?sz(); constexpr?int?nsize?=?new_sz(mf); //constexpr?int?wrong_size?=?new_sz(out_i);?//?error:?out_i?is?not?a?constexpr cout<<"test?constexpr:?"<<mf<<'\t'<<limit<<'\t'<<p4<<'\t'<<size<<'\t'<<nsize<<'\t'<<p6<<'\t'<<p7<<endl; |
noexcept
noexcept可以用作異常指示符,用于指示一個(gè)函數(shù)是否會(huì)拋出異常。編譯器并不檢查使用了noexcept的函數(shù)是否真的不拋出異常,在運(yùn)行時(shí),如果一個(gè)使用noexcept承諾不拋出異常的函數(shù)實(shí)際拋出了異常,那么程序會(huì)直接終止。
| 1 2 3 4 5 6 | void?no_except()?noexcept { ????throw?1; } //?the?following?call?will?cause?terminate //no_except(); |
noexcept還可以帶參數(shù),noexcept(true)表示不會(huì)拋出異常,noexcept(false)表示可能拋出異常。
同時(shí)noexcept還可以用作運(yùn)算符,接受一個(gè)函數(shù)調(diào)用,返回一個(gè)bool值表示是否會(huì)拋出異常。noexcept運(yùn)算符并不會(huì)對(duì)其實(shí)參進(jìn)行求值。
將noexcept運(yùn)算符,結(jié)合帶參數(shù)的noexcept指示符,可以得到如下常用法:
| 1 2 | void?no_except2()?noexcept(noexcept(no_except())){} cout<<"test?noexcept:?"<<noexcept(no_except())<<'\t'<<noexcept(no_except2())<<endl; |
這種用法表示no_except2和no_except的異常說(shuō)明保持一致。
初始化
列表初始化
C++11新標(biāo)準(zhǔn)中為很多類型增加了列表初始化的功能。
可以用列表初始化一個(gè)簡(jiǎn)單變量。
| 1 2 3 | int?single_int1?=?0; int?single_int2?=?{0}; cout<<"test?list?initialization:\n"<<single_int1<<'\t'<<single_int2<<endl; |
可以用列表初始化一個(gè)容器(vector,list,map,set…)。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //?vector/list?list?initialization vector<string>?v1?=?{"ab",?"cd",?"ef"}; list<string>?l2{"gh",?"ij",?"kl"}; //vector<string>?v3("mn",?"op",?"qr");?//?wrong?initialization?format cout<<"test?vector/list?list?initialization:\n"<<v1[1]<<'\t'<<l2.front()<<endl; //?map/set?list?initialization map<string,?string>?m1?= { ????{"a",?"A"}, ????{"b",?"B"}, ????{"c",?"C"} }; m1.insert({"d",?"D"}); set<string>?s1?=?{"a",?"b",?"c"}; cout<<"test?map/set?list?initialization:\n"<<m1["d"]<<'\t'<<*s1.find("b")<<endl; |
可以在使用new動(dòng)態(tài)分配內(nèi)存時(shí)使用列表初始化。
| 1 2 3 | vector<int>?*pv?=?new?vector<int>{0,?1,?2,?3,?4}; int?*pi?=?new?int[5]{0,?1,?2,?3,?4}; cout<<"test?new?alloator?using?list?initialization:\n"<<(*pv)[2]<<'\t'<<pi[2]<<endl; |
可以在傳入?yún)?shù)/函數(shù)返回值時(shí)使用列表初始化。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | m1.insert({"d",?"D"}); vector<string>?error_msg(int?typ) { ????switch(typ) ????{ ????????case?1: ????????????return?{"type1",?"msg1"}; ????????case?2: ????????????return?{"type2",?"msg2"}; ????????default: ????????????return?{}; ????} } pair<string,?string>?get_pair(int?typ) { ????if(typ?==?1)?return?{"key",?"value"}; ????return?pair<string,?string>("default?key",?"default?value"); } vector<string>?err_msg1?=?error_msg(1); vector<string>?err_msg2?=?error_msg(2); vector<string>?err_msg3?=?error_msg(3); cout<<"test?return?value?list?initialization:\n"<<err_msg1[1]<<'\t'<<err_msg2[1]<<'\t'<<err_msg3.empty()<<endl; pair<string,?string>?p1?=?get_pair(1); pair<string,?string>?p2?=?get_pair(2); cout<<"test?return?pair?list?initialization:\n"<<p1.first<<'\t'<<p2.first<<endl; |
類內(nèi)成員初始化
C++11標(biāo)準(zhǔn)中允許直接對(duì)類內(nèi)成員進(jìn)行初始化/列表初始化。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | class?InitClass { ????public: ????????void?print_class() ????????{ ????????????cout<<field1<<'\t'<<field2<<'\t'<<field3<<'\t'<<field4<<endl; ????????} ????private: ????????int?field1?=?1; ????????int?field2; ????????double?field3?=?1.0; ????????double?field4; }; class?InitClassMgr { ????public: ????????vector<InitClass>?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(); |
總結(jié)
·?long long類型。
· nullptr字面量用于表示空指針。
· constexpr用于表示常量表達(dá)式。
· noexcept可以用于指示一個(gè)函數(shù)是否會(huì)拋出異常,同時(shí)可以用作運(yùn)算符判定一個(gè)函數(shù)是否承諾不拋出異常。
· 新增基礎(chǔ)類型、容器類型、new分配內(nèi)存時(shí)的列表初始化。構(gòu)建臨時(shí)變量時(shí)也可以直接使用列表初始化。
· 可以直接對(duì)類內(nèi)成員進(jìn)行初始化/列表初始化。
完整代碼詳見new_type_and_keywords.cpp 和 initialize.cpp。
來(lái)源:一根笨茄子的博客
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的C++11新特性之新类型与初始化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小心Redis漏洞让你服务器沦为肉鸡
- 下一篇: 程序员应该知道的七个图形工具