程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++11之初始化列表

c++11之初始化列表

編輯:C++入門知識

一、前言
C++的學習中,我想每個人都被變量定義和申明折磨過,比如我在大學筆試過的幾家公司,都考察了const和變量,類型的不同排列組合,讓你區別有啥不同。反正在學習C++過程中已經被折磨慣了,今天再來看看重溫下那段“輝煌的歷史”。先來看一段代碼:

    Player pa;                              // (a)
    Player pb();                            // (b)
    Player pc = Player();                   // (c)  
    Player pd(Player());                    // (d)    
    pd = Player()                           // (e)


a,b,c,d 都是申明一個變量,a 很容易理解就是申明一個變量,b第一感覺是函數申明,其實不是,而是對象申明。對於c以為是調用了operator= 賦值運算吧?完全不是,而是先生成一個對象,然後調用Player的拷貝構造函數,生成對象pc。d和c是一樣的。e才是真正調用賦值操作。是不是已經被這各式各樣的對象申明搞的暈頭專向了。現在C++11初始化列表正式登場。
二、簡介
在看C++11初始化前,先來回憶一下C語言中的結構體初始化,代碼如下:
#include 

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 va{1, 2, 3};          // (a)
    std::vector vb = {1, 2, 3};       // (b)    
    std::vector vc(1, 10);            // (c)   
    std::vector vd{1, 10};            // (d)  

通過初始化列表可以彌補c中只能初始化相同數字的問題。在使用中c和d不要混淆了。
    std::pair getPlayer() {
         return {10001, "c++"};
     }
    std::map 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 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 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類型,不可轉換

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved