日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747


C++11標準庫新加功能詳解

 

一、Lambda表達式的引進

Lambda表達式的形式是這樣的:

[capture](parameters)->return-type{body}

來看個計數某個字符序列中有幾個大寫字母的例子:

1. intmain()

2. {

3. chars[]="HelloWorld!";

4. intUppercase=0;//modifiedbythelambda

5. for_each(s,s+sizeof(s),[&Uppercase](charc){

6. if(isupper(c))

7. Uppercase++;

8. });

9. cout<<Uppercase<<"uppercaselettersin:"<<s<<endl;

10. }

其中[&Uppercase]中的 &的意義是 lambda函數體要獲取一個 Uppercase引用,以便能夠改變它的值,如果沒有 &,那就 Uppercase將以傳值的形式傳遞過去。

二、自動類型推導和decltype

在 C++03中,聲明對象的同時必須指明其類型,其實大多數情況下,聲明對象的同時也會包括一個初始值,C++11在這種情況下就能夠讓你聲明對象時不再指定類型了:

1. autox=0;//0是int類型,所以x也是int類型

2. autoc='a';//char

3. autod=0.5;//double

4. autonational_debt=14400000000000LL;//longlong

這個特性在對象的類型很大很長的時候很有用,如:

1. voidfunc(constvector<int>&vi)

2. {

3. vector<int>::const_iteratorci=vi.begin();

4. }

那個迭代器可以聲明為:

1. autoci=vi.begin();

C++11也提供了從對象或表達式中“俘獲”類型的機制,新的操作符decltype可以從一個表達式中“俘獲”其結果的類型并“返回”:

1. constvector<int>vi;

2. typedefdecltype(vi.begin())CIT;

3. CITanother_const_iterator;

三、統一的初始化語法

C++最少有 4種不同的初始化形式,如括號內初始化,見:

1. std::strings("hello");

2. intm=int();//defaultinitialization

還有等號形式的:

1. std::strings="hello";

2. intx=5;

對于 POD集合,又可以用大括號:

1. intarr[4]={0,1,2,3};

2. structtmtoday={0};

最后還有構造函數的成員初始化:

1. structS{

2. intx;

3. S():x(0){}};

這么多初始化形式,不僅菜鳥會搞得很頭大,高手也吃不消。更慘的是 C++03中居然不能初始化POD數組的類成員,也不能在使用 new[]的時候初始 POD數組!C++11就用大括號一統天下了:

1. classC

2. {

3. inta;

4. intb;

5. public:

6. C(inti,intj);

7. };

8. Cc{0,0};//C++11only.相當于Cc(0,0);

9. int*a=newint[3]{1,2,0};/C++11only

10. classX{

11. inta[4];

12. public:

13. X():a{1,2,3,4}{}//C++11,初始化數組成員

14. };

還有一大好事就是對于容器來說,終于可以擺脫push_back()調用了,C++11中可以直觀地初始化容器了:

1. //C++11containerinitializer

2. vectorvs<string>={"first","second","third"};

3. mapsingers=

4. {{"LadyGaga","+1(212)555-7890"},

5. {"BeyonceKnowles","+1(212)555-0987"}};

而類中的數據成員初始化也得到了支持:

1. classC

2. {

3. inta=7;//C++11only

4. public:

5. C();

6. };

四.deleted函數和 defaulted函數

像以下形式的函數:

1. structA

2. {

3. A()=default;//C++11

4. virtual~A()=default;//C++11

5. };

叫做 defaulted函數,=default;指示編譯器生成該函數的默認實現。這有兩個好處:一是讓程序員輕松了,少敲鍵盤,二是有更好的性能。

與 defaulted函數相對的就是 deleted函數:

1. intfunc()=delete;

這貨有一大用途就是實現 noncopyabe防止對象拷貝,要想禁止拷貝,用 =deleted聲明一下兩個關鍵的成員函數就可以了:

structNoCopy

{

NoCopy&operator=(constNoCopy&)=delete;

NoCopy(constNoCopy&)=delete;

};

NoCopya;

NoCopyb(a);//編譯錯誤,拷貝構造函數是deleted函數

nullptr

nullptr是一個新的 C++關鍵字,它是空指針常量,它是用來替代高風險的 NULL宏和 0字面量的。nullptr是強類型的:

voidf(int);//#1

voidf(char*);//#2

//C++03

f(0);//調用的是哪個f?

//C++11

f(nullptr)//毫無疑問,調用的是#2

所有跟指針有關的地方都可以用nullptr,包括函數指針和成員指針:

constchar*pc=str.c_str();//datapointers

if(pc!=nullptr)

cout<<pc<<endl;

int(A::*pmf)()=nullptr;//指向成員函數的指針

void(*pmf)()=nullptr;//指向函數的指針

委托構造函數

C++11中構造函數可以調用同一個類的另一個構造函數:

classM//C++11delegatingconstructors

{

intx,y;

char*p;

public:

M(intv):x(v),y(0),p(newchar[MAX]){}//#1target

M():M(0){cout<<"delegatingctor"<<end;}//#2delegating

#2就是所謂的委托構造函數,調用了真正的構造函數 #1。

右值引用

在 C++03中的引用類型是只綁定左值的,C++11引用一個新的引用類型叫右值引用類型,它是綁定到右值的,如臨時對象或字面量。

增加右值引用的主要原因是為了實現 move語義。與傳統的拷貝不同,move的意思是目標對象“竊取”原對象的資源,并將源置于“空”狀態。當拷貝一個對象時,其實代價昂貴且無必要,move操作就可以替代它。如在 string交換的時候,使用 move意義就有巨大的性能提升,如原方案是這樣的:

voidnaiveswap(string&a,string&b)

{

stringtemp=a;

a=b;

b=temp;

}

這種方案很傻很天真,很慢,因為需要申請內存,然后拷貝字符,而 move就只需要交換兩個數據成員,無須申請、釋放內存和拷貝字符數組:

voidmoveswapstr(string&empty,string&filled)

{

//pseudocode,butyougettheidea

size_tsz=empty.size();

constchar*p=empty.data();

//movefilled'sresourcestoempty

empty.setsize(filled.size());

empty.setdata(filled.data());

//filledbecomesempty

filled.setsize(sz);

filled.setdata(p);

}

要實現支持 move的類,需要聲明 move構造函數和 move賦值操作符,如下:

classMovable

{

Movable(Movable&&);//moveconstructor

Movable&&operator=(Movable&&);//moveassignmentoperator

};

C++11的標準庫廣泛使用 move語義,很多算法和容器都已經使用 move語義優化過了。

C++11的標準庫

除TR1包含的新容器(unordered_set,unordered_map, unordered_multiset,和unordered_multimap),還有一些新的庫,如正則表達式,tuple,函數對象封裝器等。下面介紹一些 C++11 的標準庫新特性:

線程庫

從程序員的角度來看,C++11最重要的特性就是并發了。C++11提供了 thread類,也提供了 promise和 future用以并發環境中的同步,用 async()函數模板執行并發任務,和 thread_local存儲聲明為特定線程獨占的數據,這里(http://www.devx.com/SpecialReports/Article/38883)有一個簡單的 C++11線程庫教程(英文)。

新的智能指針類

C++98定義的唯一的智能指針類auto_ptr已經被棄用,C++11引入了新的智能針對類shared_ptr和unique_ptr。它們都是標準庫的其它組件兼容,可以安全地把智能指針存入標準容器,也可以安全地用標準算法“倒騰”它們。

新的算法

主要是 all_of()、any_of()和 none_of(),下面是例子:

#include<algorithm>

//C++11code

//arealloftheelementspositive?

all_of(first,first+n,ispositive());//false

//isthereatleastonepositiveelement?

any_of(first,first+n,ispositive());//true

//arenoneoftheelementspositive?

none_of(first,first+n,ispositive());//false

還有一個新的 copy_n:

#include<algorithm>

intsource[5]={0,12,34,50,80};

inttarget[5];

//從source拷貝5個元素到target

copy_n(source,5,target);

iota()算法可以用來創建遞增序列,它先把初值賦值給 *first,然后用前置 ++ 操作符增長初值并賦值到給下一個迭代器指向的元素,如下:

#include<numeric>

inta[5]={0};

charc[3]={0};

iota(a,a+5,10);//changesato{10,11,12,13,14}

iota(c,c+3,'a');//{'a','b','c'}

到現在為至,C++11仍然缺少一些很有用的庫如XML API,socket,GUI、反射——以及自動垃圾收集。然而現有特性已經讓 C++ 更安全、高效(是的,效率更高了,可以參見 google的基準測試結果:

http://www.itproportal.com/2011/06/07/googles-rates-c-most-complex-highest-performing-language/

以及更加易于學習和使用。

分享到:
標簽:標準
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定