• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-59  評(píng)論-36  文章-0  trackbacks-0

            賴勇浩(http://laiyonghao.com)
            聲明:本文源自 Danny Kalev 在 2011 年 6 月 21 日發(fā)表的《The Biggest Changes in C++11(and Why You Should Care)》一文,幾乎所有內(nèi)容都搬了過來,但不是全文照譯,有困惑之處,請(qǐng)參詳原文(http://www.softwarequalityconnection.com/2011/06/the-biggest-changes-in-c11-and-why-you-should-care/ )。
            注:作者 Danny Kalev 曾是 C++ 標(biāo)準(zhǔn)委員會(huì)成員。

            Lambda 表達(dá)式

            Lambda 表達(dá)式的形式是這樣的:

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

            來看個(gè)計(jì)數(shù)某個(gè)字符序列中有幾個(gè)大寫字母的例子:
            1. int main()  
            2. {  
            3.    char s[]="Hello World!";  
            4.    int Uppercase = 0; //modified by the lambda  
            5.    for_each(s, s+sizeof(s), [&Uppercase] (char c) {  
            6.     if (isupper(c))  
            7.      Uppercase++;  
            8.     });  
            9.  cout<< Uppercase<<" uppercase letters in: "<< s<<endl;  
            10. }  

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

            自動(dòng)類型推導(dǎo)和 decltype

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

            1. auto x=0; //0 是 int 類型,所以 x 也是 int 類型  
            2. auto c='a'; //char  
            3. auto d=0.5; //double  
            4. auto national_debt=14400000000000LL;//long long  

            這個(gè)特性在對(duì)象的類型很大很長的時(shí)候很有用,如:
            1. void func(const vector<int> &vi)  
            2. {  
            3.   vector<int>::const_iterator ci=vi.begin();  
            4. }  

            那個(gè)迭代器可以聲明為:
            1. auto ci=vi.begin();  

            C++11 也提供了從對(duì)象或表達(dá)式中“俘獲”類型的機(jī)制,新的操作符 decltype 可以從一個(gè)表達(dá)式中“俘獲”其結(jié)果的類型并“返回”:
            1. const vector<int> vi;  
            2. typedef decltype (vi.begin()) CIT;  
            3. CIT another_const_iterator;  

            統(tǒng)一的初始化語法

            C++ 最少有 4 種不同的初始化形式,如括號(hào)內(nèi)初始化,見:

            1. std::string s("hello");  
            2. int m=int(); //default initialization  

            還有等號(hào)形式的:
            1. std::string s="hello";  
            2. int x=5;  

            對(duì)于 POD 集合,又可以用大括號(hào):
            1. int arr[4]={0,1,2,3};  
            2. struct tm today={0};  

            最后還有構(gòu)造函數(shù)的成員初始化:
            1. struct S {  
            2.  int x;  
            3.  S(): x(0) {} };  

            這么多初始化形式,不僅菜鳥會(huì)搞得很頭大,高手也吃不消。更慘的是 C++03 中居然不能初始化 POD 數(shù)組的類成員,也不能在使用 new[] 的時(shí)候初始 POD 數(shù)組,操蛋啊!C++11 就用大括號(hào)一統(tǒng)天下了:
            1. class C  
            2. {  
            3. int a;  
            4. int b;  
            5. public:  
            6.  C(int i, int j);  
            7. };  
            8. C c {0,0}; //C++11 only. 相當(dāng)于 C c(0,0);  
            9. int* a = new int[3] { 1, 2, 0 }; /C++11 only  
            10. class X {  
            11.   int a[4];  
            12. public:  
            13.   X() : a{1,2,3,4} {} //C++11, 初始化數(shù)組成員  
            14. };  

            還有一大好事就是對(duì)于容器來說,終于可以擺脫 push_back() 調(diào)用了,C++11中可以直觀地初始化容器了:
            1. // C++11 container initializer  
            2. vector vs<string>={ "first", "second", "third"};  
            3. map singers =  
            4.   { {"Lady Gaga", "+1 (212) 555-7890"},  
            5.     {"Beyonce Knowles", "+1 (212) 555-0987"}};  

            而類中的數(shù)據(jù)成員初始化也得到了支持:
            1. class C  
            2. {  
            3.  int a=7; //C++11 only  
            4. public:  
            5.  C();  
            6. };  

            deleted 函數(shù)和 defaulted 函數(shù)

            像以下形式的函數(shù):

            1. struct A  
            2. {  
            3.  A()=default; //C++11  
            4.  virtual ~A()=default; //C++11  
            5. };  

            叫做 defaulted 函數(shù),=default; 指示編譯器生成該函數(shù)的默認(rèn)實(shí)現(xiàn)。這有兩個(gè)好處:一是讓程序員輕松了,少敲鍵盤,二是有更好的性能。
            與 defaulted 函數(shù)相對(duì)的就是 deleted 函數(shù):
            1. int func()=delete;  

            這貨有一大用途就是實(shí)現(xiàn) noncopyabe 防止對(duì)象拷貝,要想禁止拷貝,用 =deleted 聲明一下兩個(gè)關(guān)鍵的成員函數(shù)就可以了:
            1. struct NoCopy  
            2. {  
            3.     NoCopy & operator =( const NoCopy & ) = delete;  
            4.     NoCopy ( const NoCopy & ) = delete;  
            5. };  
            6. NoCopy a;  
            7. NoCopy b(a); //編譯錯(cuò)誤,拷貝構(gòu)造函數(shù)是 deleted 函數(shù)  

            nullptr

            nullptr 是一個(gè)新的 C++ 關(guān)鍵字,它是空指針常量,它是用來替代高風(fēng)險(xiǎn)的 NULL 宏和 0 字面量的。nullptr 是強(qiáng)類型的:

            1. void f(int); //#1  
            2. void f(char *);//#2  
            3. //C++03  
            4. f(0); //調(diào)用的是哪個(gè) f?  
            5. //C++11  
            6. f(nullptr) //毫無疑問,調(diào)用的是 #2  

            所有跟指針有關(guān)的地方都可以用 nullptr,包括函數(shù)指針和成員指針:
            1. const char *pc=str.c_str(); //data pointers  
            2. if (pc!=nullptr)  
            3.   cout<<pc<<endl;  
            4. int (A::*pmf)()=nullptr; //指向成員函數(shù)的指針  
            5. void (*pmf)()=nullptr; //指向函數(shù)的指針  

            委托構(gòu)造函數(shù)

            C++11 中構(gòu)造函數(shù)可以調(diào)用同一個(gè)類的另一個(gè)構(gòu)造函數(shù):

            1. class M //C++11 delegating constructors  
            2. {  
            3.  int x, y;  
            4.  char *p;  
            5. public:  
            6.  M(int v) : x(v), y(0),  p(new char [MAX])  {} //#1 target  
            7.  M(): M(0) {cout<<"delegating ctor"<<end;} //#2 delegating  

            #2 就是所謂的委托構(gòu)造函數(shù),調(diào)用了真正的構(gòu)造函數(shù) #1。

            右值引用

            在 C++03 中的引用類型是只綁定左值的,C++11 引用一個(gè)新的引用類型叫右值引用類型,它是綁定到右值的,如臨時(shí)對(duì)象或字面量。
            增加右值引用的主要原因是為了實(shí)現(xiàn) move 語義。與傳統(tǒng)的拷貝不同,move 的意思是目標(biāo)對(duì)象“竊取”原對(duì)象的資源,并將源置于“空”狀態(tài)。當(dāng)拷貝一個(gè)對(duì)象時(shí),其實(shí)代價(jià)昂貴且無必要,move 操作就可以替代它。如在 string 交換的時(shí)候,使用 move 意義就有巨大的性能提升,如原方案是這樣的:

            1. void naiveswap(string &a, string & b)  
            2. {  
            3.  string temp = a;  
            4.  a=b;  
            5.  b=temp;  
            6. }  

            這種方案很傻很天真,很慢,因?yàn)樾枰暾?qǐng)內(nèi)存,然后拷貝字符,而 move 就只需要交換兩個(gè)數(shù)據(jù)成員,無須申請(qǐng)、釋放內(nèi)存和拷貝字符數(shù)組:
            1. void moveswapstr(string& empty, string & filled)  
            2. {  
            3. //pseudo code, but you get the idea  
            4.  size_t sz=empty.size();  
            5.  const char *p= empty.data();  
            6. //move filled's resources to empty  
            7.  empty.setsize(filled.size());  
            8.  empty.setdata(filled.data());  
            9. //filled becomes empty  
            10.  filled.setsize(sz);  
            11.  filled.setdata(p);  
            12. }  

            要實(shí)現(xiàn)支持 move 的類,需要聲明 move 構(gòu)造函數(shù)和 move 賦值操作符,如下:
            1. class Movable  
            2. {  
            3. Movable (Movable&&); //move constructor  
            4. Movable&& operator=(Movable&&); //move assignment operator  
            5. };  

            C++11 的標(biāo)準(zhǔn)庫廣泛使用 move 語義,很多算法和容器都已經(jīng)使用 move 語義優(yōu)化過了。

            C++11 的標(biāo)準(zhǔn)庫

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

            線程庫

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

            新的智能指針類

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

            新的算法

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

            1. #include <algorithm>  
            2. //C++11 code  
            3. //are all of the elements positive?  
            4. all_of(first, first+n, ispositive()); //false  
            5. //is there at least one positive element?  
            6. any_of(first, first+n, ispositive());//true  
            7. // are none of the elements positive?  
            8. none_of(first, first+n, ispositive()); //false  

            還有一個(gè)新的 copy_n:
            1. #include <algorithm>  
            2. int source[5]={0,12,34,50,80};  
            3. int target[5];  
            4. //從 source 拷貝 5 個(gè)元素到 target  
            5. copy_n(source,5,target);  

            iota() 算法可以用來創(chuàng)建遞增序列,它先把初值賦值給 *first,然后用前置 ++ 操作符增長初值并賦值到給下一個(gè)迭代器指向的元素,如下:
            1. #include <numeric>  
            2. int a[5]={0};  
            3. char c[3]={0};  
            4. iota(a, a+5, 10); //changes a to {10,11,12,13,14}  
            5. iota(c, c+3, 'a'); //{'a','b','c'}  

            是的,C++11 仍然缺少一些很有用的庫如 XML API,socket,GUI、反射——以及自動(dòng)垃圾收集。然而現(xiàn)有特性已經(jīng)讓 C++ 更安全、高效(是的,效率更高了,可以參見 Google 的 基準(zhǔn)測試結(jié)果http://www.itproportal.com/2011/06/07/googles-rates-c-most- complex-highest-performing-language/)以及更加易于學(xué)習(xí)和使用。
            如果覺得 C++ 變化太大了,不必驚恐,花點(diǎn)時(shí)間來學(xué)習(xí)就好了。可能在你融會(huì)貫通新特性以后,你會(huì)同意 Stroustrup 的觀點(diǎn):C++11 是一門新的語言——一個(gè)更好的 C++。


            posted on 2011-08-19 21:06 zhaoyg 閱讀(825) 評(píng)論(2)  編輯 收藏 引用 所屬分類: C/C++學(xué)習(xí)筆記

            評(píng)論:
            # re: 【轉(zhuǎn)】C++11中值得關(guān)注的幾大變化 2012-05-28 03:09 | RUSSELLMaryann34
            If you are in not good state and have no money to get out from that point, you would require to take the <a href="http://goodfinance-blog.com/topics/mortgage-loans">mortgage loans</a>. Because it should help you unquestionably. I take short term loan every single year and feel myself OK just because of that.   回復(fù)  更多評(píng)論
              
            亚洲精品tv久久久久久久久 | 欧美牲交A欧牲交aⅴ久久 | 亚洲一本综合久久| 亚洲成色www久久网站夜月| 伊人久久成人成综合网222| 国内精品免费久久影院| 精品国产一区二区三区久久蜜臀 | 青青青伊人色综合久久| 国产产无码乱码精品久久鸭| 欧美精品久久久久久久自慰| 久久99国产综合精品| 久久无码人妻一区二区三区午夜| 欧美黑人又粗又大久久久| 久久精品黄AA片一区二区三区| 久久影院综合精品| 亚洲伊人久久大香线蕉苏妲己| 色噜噜狠狠先锋影音久久| 99久久伊人精品综合观看| 国内精品久久久久久麻豆| 日韩精品久久久久久久电影| 婷婷五月深深久久精品| 国产一区二区三区久久| 国产精品99久久久久久猫咪| 久久久久久久久久久免费精品| 伊人久久国产免费观看视频| 久久午夜羞羞影院免费观看| 久久99久久无码毛片一区二区| 免费一级做a爰片久久毛片潮| 久久经典免费视频| 国产精品久久久久久搜索| 久久久久九国产精品| 日本久久久久亚洲中字幕| 国产成人无码精品久久久免费| 亚洲国产婷婷香蕉久久久久久| 综合网日日天干夜夜久久| 国产亚洲成人久久| 久久国产精品一国产精品金尊| 久久久久婷婷| 好属妞这里只有精品久久| 久久免费看黄a级毛片| 精品国产91久久久久久久a|