C++11之初始化成員變量

C++98中的成員變量初始化

  • 在聲明類的時候,對於靜態類型並且是常量類型,同時是枚舉或者是整型的變量可以使用=在聲明時初始化。
  • 對於不符合上述要求的靜態變量可以在類外使用=進行初始化
  • 對於非靜態類型可以說個初始化列表進行初始化
  • 使用()對自定義類型進行初始化
  • 使用{}對元素集合統一初始化

C++11中的成員變量初始化

在C++11中可以使用=或者{}就地初始化,類似於Java語言。
代碼示例

struct init{
    int a  = 1;
    double b{1.2};
};

需要注意的是()不能與=和{}有相同的使用方式,代碼示例

#include<iostream>
using namspace std;

struct C
{
    C(int i):c(i){};
    int  c;
};

struct init
{
    int a = 1;
    string b("test");//編譯通不過
    C c(1);          //編譯通不過
};

需要注意的是=和{}可以和初始化列表一起使用,而且初始化列表總是後作用於=和{}

C++11豐富{}初始化

使用{}豐富化向量初始化,代碼示例

#include<vector>
#include<map>
using namespace std;

int a[] = {1. 3. 5};
int b[] {2. 4. 6};
vector<int> c{1, 3, 5};
map<int, float> d = {{1, 1.0f}, {2, 2.0f}, {3, 3.0f}};
int f = {3 + 4};
int g(3 + 4);            //可以與new結合用來申請堆內存
int h{3 + 4};            //可以與new結合用來申請堆內存

以上代碼在C++11中可以順利通過編譯,但是在C++98中確不可以通過編譯。可以發現上面的代碼的初始化列表僅在基本類型和stl元素可以使用,對於那些自定義類型,可以通過修改構造函數、重載運算符等操作。

示例代碼

#include<iostream>
#include<vector>

using namespace std;

class Mydata{
public:
    Mydata& operator[] (initializer_list<int> l)
    {
        for(auto i = l.begin(); i != l.end(); i++)
            idx.push_back(*i);
        return *this;
    }

    Mydata& operator = (int v)
    {
        for(auto i = idx.begin(); i != idx.end(); i++)
        {
            d.resize((*i > d.size())? *i: d.size());
            d[*i - 1] = v;
            cout << v << endl;
        }
        idx.clear();

        return *this;
    }

    void print()
    {
        for(auto i = d.begin(); i != d.end(); i++)
            cout << *i << "   " ;
    }
private:
    vector<int> idx;
    vector<int> d;
};

int main()
{
    Mydata d;
    d[{2, 3, 5}] = 90;
    d[{1, 4, 5, 8}] = 7;
    d.print();
    return 0;

}

{}初始化列表的優點

與其他的初始化方式相比,{}初始化是唯一一種可以防止類型收窄的初始化方式。所謂的類型收窄其實就是新類型不可以表示原來類型的情況,在類型轉換的過程中數據丟失。
示例代碼


#include<iostream>
using namespace std;


int main()
{
    const int x = 1024;
    const int y = 10;

    char a = x;       //收窄,編譯可以通過
    char *b = new char(1024);//收窄,編譯可以通過

    char c = {x};   //收窄,編譯可以通過
    char d = {y};   //編譯可以通過
    unsigned char e {-1}; //收窄,編譯無法通過

    float f{ 7 }; //編譯可以通過
    int g { 2.0f };       //收窄,編譯無法通
    float *h = new float{1e48};  //收窄,編譯無法通
    float i = 1.2l; //可以通過編譯

    return 0;
}

參考鏈接
C++11中新特性之:initializer_list詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章