結構體的vector resize()與初始化

序:
我們在使用vector的時候可以自定義裏面的數據類型。例如這樣:

struct Edge{
    int from;
    int to;
    int weight;
};
vector<Edge> edge;

使用vector的使用我們有時會用到resizereserve函數進行內存的分配。在之前的測試中我們發現先使用resize再用下標訪問讀取數據的效率要遠遠高於push_back()(測試結果見下),所以resize函數在初始化的時候會被使用。
關於vector push_back()與其他方式讀取數據的效率對比
但是當我們真的調用resize函數的時候,編譯器會報錯:

edge.resize(0);
---
[Error] no matching function for call to 'Edge::Edge()'
[Note] candidates are:

難道是調用resize的時候格式出了問題嗎?
但是卻發現下面的:

vector<int> arc[maxn];
arc[i].resize(0);

沒有任何問題
那麼自定義結構體與int這類數據類型到底哪裏不同

後來我們發現加上它就不會報錯了:

struct Edge{
    int from;
    int to;
    int weight;
    Edge(){} /* 重點在這裏 */
    Edge(int f, int t, int w):
        from(f), to(t), weight(w){}/* 這個不是重點 */
};

原來當執行resize的時候,如果我們將它擴大,編譯器會自動將剩下的部分初始化。int的初始化爲0,但是我們自定義的結構體沒有初始化函數。所以它無法執行。
類似的,當我們直接聲明一個結構體數組的時候:

Edge edge[maxn];

發生報錯的原因也在於此,由於vector在聲明的時候不會執行初始化所以沒有報錯。但是聲明一個數組,編譯器會將整個數組初始化,這就需要你手寫一個初始化的函數。(可以是空,也可以在裏面寫你要的特殊初始化,但是必須要有)而且這個初始化的函數參數是空的,函數名就是結構體的名字(你初始化的時候沒有參數),跟普通的函數一個意思,只不過是寫在了結構體的內部。


那麼再看下面不是重點的那兩行代碼:

Edge(int f, int t, int w):
        from(f), to(t), weight(w){}

這個就是有參數的初始化了。當你讀入多個數據構造結構體的時候,這樣做會讓代碼很簡潔
不用的話是這樣的:

n = Get_Int(), m = Get_Int(), we = Get_Int();//讀入優化
edge[i].from = n;
edge[i].to = m;
...

有了它代碼會是這樣的:

n = Get_Int ...; /* 輸入同上 */
edge[i] = Edge(n, m, we);

明顯簡潔了很多。

fread讀入優化,尋找速度極限


自此結束。

箜瑟_qi 2017.04.22 11:35

發佈了44 篇原創文章 · 獲贊 40 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章