C++ 11中幾個我比較喜歡的文法

來源:互聯網
上載者:User

C++11的標準已經確定,除了增加了不少庫函數外,在文法方便也得到了許多增強。其中如下幾個文法就是我比較喜歡的:

自動類型推導auto

現在c++終於在編譯器層級支援類似C#的var關鍵字了,在c++裡的關鍵字是auto,基本用法如下:

    auto i = 0;        //int
    auto c = 'c';    //char
    auto s = "hello world";    //const char*

auto關鍵字的一個很直觀的好處是我們可以簡化stl容器遍曆裡的那個iterator了:

    for(auto it = v.begin(); it != v.end(); it++)
    {
        cout << *it << endl;
    }

Lambda 運算式

Lambda 運算式的主要用來構造匿名函數,它可以替換絕大部分情境的仿函數(感覺把剛剛引入STL庫的std::bind也順手給秒了),並且有更好的可讀性。一個簡單的樣本如下:

    auto k = [](int
x, int
y) { return
x + y; };
    cout << k(3, 2) << endl;

可以看到,它的基本文法形式為: [capture] (parameters) {body},後兩部分和C#的匿名函數的文法非常,但最前面的 [capture]
的作用是什麼呢?它是用來參考資料表達式外的局部變數的,例如:

    int i1 = 0, i2 = 3;
    auto k = [&i1, &i2] () { i1 = 3; i2 = 5; };
    cout << i1 << " " << i2 << endl;

除了是前面所述的普通局部變數外,還可以是如下特殊符號:

  • =    所有局部變數,以按值的方式傳遞(包括this指標)
  • &    所有局部變數,以按引用的方式傳遞(包括this指標)
  • this this指標

Range-based for-loop

這個其實就是類似C#裡面的foreach,不過它並沒有引入新關鍵字,而是直接用的for

    int p[8] = {2, 3, 5, 7, 11, 13, 17, 19};
    for (auto& i: p)
    {
        printf("%d ", i);
    }

除了支援數組外,它也支援stl中的迭代器遍曆,for_each函數基本上可以下崗了。至於它的原理,可以參考這篇文章。

枚舉類

在C語言中,枚舉等同於一個數字常量,編譯器並沒有對它做過多的處理,在C++11中,引入了enum class以替換枚舉,它的定義方式如下:

    enum class
Color { Red, Blue};
    enum class
Fruit { Banana, Apple};

除了多加了一個class外,沒有別的變化,但它定義的枚舉功能和C#中的枚舉相似。和C語言的傳統枚舉相比,主要有如下兩個區別:

  1. 強型別的語法檢查
  2. 枚舉名稱只需要在class範圍內唯一

強型別的語法檢查可以有效防止枚舉之間的非法轉換和比較,Color::Red == Fruit::Banana之類的判斷無法編譯通過。

而枚舉名稱只需要在class範圍內唯一則有效縮短了枚舉的長度,對於Color枚舉,在C語言中,為了防止歧義和命名衝突,往往需要定義為Color_Red、Color_Blue的形式。

靜態斷言static_assert

靜態斷言主要提供了在代碼中實現編譯期可以確定的斷言,如果出錯則直接以編譯錯誤的形式顯示出來,從而加強程式的健壯性。這個其實就是以前的boost.static_assert,不過在編譯器的支援下變得更加友好了。樣本如下:

    static_assert(sizeof(int) == 4, "int needs to be 4 bytes to use this code");

密閉類和密閉方法

C++11中也引入了類似C# seal關鍵字的方式實現密閉類和密閉方法,以阻止對象繼承、方法重載。不過它的關鍵字是final,和java類似。

    final類

    class
Base final
    {
    };
    class
Derived : public
Base
//繼承密閉類,語法錯誤
    {
    };

    final方法

    class
Base
    {
        virtual
void A() final;
    };
    class
Derived : public
Base

    {
        virtual
void A(); //重寫密閉方法,編譯出錯
    };

顯式覆蓋

對於虛函數的重寫,在c++ 11中可以通過關鍵字顯式覆蓋,從而獲得更嚴格的語法檢查。

    class
Base
    {
        virtual
void A(float=0.0);
        virtual
void B() const;
        virtual
void C();
        void D();
    };
    class
Derived: public
Base
    {
        virtual
void A(int=0) override; //定義不一致,編譯錯誤
        virtual
void B() override;        //傳回型別不是const,編譯錯誤
        virtual
void C() override;        //正確
        void D() override;                //不是虛函數,編譯錯誤
    };

PS:我倒覺得這個語法檢查應該預設就加上,通過關鍵字顯式去掉檢查,而不是像這樣顯式開啟檢查。萬惡的向上相容呀。

其它

其它還有幾個文法我也很喜歡,如取消字串轉義、委託建構函式、deleted和defaulted成員函數、統一的初始化文法等,但這些在VC裡面還不支援,無法實現跨平台開發,暫時就不介紹了。

補充:C++ 11中幾個我比較喜歡的文法(二)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.