c++11之初始化列表

來源:互聯網
上載者:User

標籤:google   前言   strong   學習   使用   曆史   iostream   pos   結構   

一、前言
     C++的學習中。我想每一個人都被變數定義和申明折磨過,比方我在大學筆試過的幾家公司。都考察了const和變數,類型的不同排列組合,讓你差別有啥不同。反正在學習C++過程中已經被折磨慣了,今天再來看看重溫下那段“輝煌的曆史”。先來看一段代碼:
    Player pa;                              // (a)    Player pb();                            // (b)    Player pc = Player();                   // (c)      Player pd(Player());                    // (d)        pd = Player()                           // (e)


a,c,d 都是申明一個變數,a 非常easy理解就是申明一個變數,b第一感覺是調用建構函式來申明變數。事實上不是,而是申明一個無參數,返回Player的函數。

對於c以為是調用了operator= 賦值運算吧?全然不是。而是先產生一個對象。然後調用Player的拷貝建構函式,產生對象pc。d和c是一樣的。e才是真正調用賦值操作。是不是已經被這各式各樣的對象申明搞的暈頭專向了。如今C++11初始化列表正式登場。
二、簡單介紹
     在看C++11初始化前,先來回顧一下C語言中的結構體初始化。代碼例如以下:

#include <iostream>struct Player{    int id;    const char* name;};int main() {    Player player = {10001, "c++"};    printf("%d, %s\n", player.id, player.name);}

     結構體變數能夠列表初始化,非常方便。

C++11引入了初始化列表來初始設定變數和對象。
三、怎樣使用

     1、系統內建類型

    int ia{1};                // (a)    int ib = {1};             // (b)       int ic(1);                // (c)     int id = 1;               // (d)

    非常明顯。還是d 更符合習慣。


    std::vector<int> va{1, 2, 3};          // (a)    std::vector<int> vb = {1, 2, 3};       // (b)        std::vector<int> vc(1, 10);            // (c)       std::vector<int> vd{1, 10};            // (d)  
 
    通過初始化列表能夠彌補c中僅僅能初始化同樣數位問題。在使用中c和d不要混淆了。
    std::pair<int, const char*> getPlayer() {         return {10001, "c++"};     }    std::map<int, const char*> players = {{10001, "c++"}, {10002, "java”}};
    
    還能夠返回pair類型。初始化map都是能夠的。



    2、自己定義類型
    對於單個參數初始化,類型匹配建構函式,不須要自己定義建構函式。

    Player pa{};                    // (a)    Player pb;                      // (b)      Player pc();                    // (c)    Player pd(b);                   // (d)    Player pe = b;                  // (e)    Player pf = {b};                // (f)



    對於上面幾種變數初始化,推薦a, 假設是帶參數的建構函式,推薦b,若果是不帶參數的建構函式。

     3、假設是自己想實現初始化列表建構函式。拷貝函數,賦值函數,須要包括initializer_list 這個標頭檔。
class MyClass{public:    MyClass(int a):a_(a){        std::cout << "normal initializer list\n";    }    MyClass(std::initializer_list<int> a):b_(a) {        std::cout << "initializer list constructor\n";    }    MyClass(MyClass& my) {        std::cout << "copy constructor\n";        this->a_ = my.a_;        this->b_ = my.b_;    }    MyClass& operator=(MyClass& my) {        std::cout << "operator = constructor\n";        this->a_ = my.a_;        this->b_ = my.b_;        return *this;    }private:    int a_;    std::initializer_list<int> b_;};


這是自己定義類,帶有初始化列表建構函式的類,以下來練習下學過的類相關C++知識:
    MyClass ma{1};               // (a)    MyClass mb = {1, 2, 3};      // (b)    MyClass mc(2);               // (c)    MyClass md = b;              // (d)    MyClass me(c);               // (e)    MyClass mf{e};               // (f)    auto l{2, 2, 3,3};    MyClass mh{l};               // (e)    ma = mb;                     // (h)



看一下每次調用都輸出什麼結果,答案在這裡:

initializer list constructor

initializer list constructor

normal constructor list

copy constructor

copy constructor

copy constructor

initializer list constructor

operator = constructor


四、為啥須要初始化列表
1、避免類申明對象混淆,區分對待,對於C++為啥有小括弧初始化對象這一說,大家能夠自行google。看來無論是誰都有犯錯誤的時候。勇於承認錯誤還是好同志。
2、在初始化多個變數時方便
3、避免資料分割,由於通過初始化列表是不同意隱式轉換的,相關知識能夠參考我的 這篇文章

五、注意事項
1、在申明變數的時候,少用小括弧,程式可讀性更高
2、使用初始化列表防止隱式轉換,降低bug
3、通過 {} 返回的對象是const類型,不可轉換

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.