2011-08-24 49 views
3

我還在路上在C++中以啓迪,讓我承擔......C風格的初始化列表,結構和類的構造函數

假設我有一個結構:

struct MyThing 
{ 
    int a, b; 
}; 

我看中使用C風格的速記創建一個,圖1:

MyThing mt = { 1, 2 }; 

然後假設我決定在我的結構某處粘的方法,以及(是什麼樣的人,我是)我覺得結構並不適合方法,所以把它變成一個類:

class MyThing 
{ 
public: 
    int a, b; 
    int sum() 
    { 
     return a + b; 
    } 
}; 

我的Fig.1仍然正常工作 - 一切都是hunky dory。然後,我決定,我會最終需要的私有方法和成員:

class MyThing 
{ 
private: 
    int c; 
    void swap() { 
     c = a; 
     a = b; 
     b = c; 
    } 
public: 
    int a, b; 
    int sum() 
    { 
     return a + b; 
    } 
}; 

在這一點上,圖1中的C風格的初始化列表編譯失敗(在VS反正)與「非聚集不能與初始化列表」初始化 - 這是很好的說明如下:http://msdn.microsoft.com/en-us/library/0s6730bb(v=vs.71).aspx

所以我切換到:

class MyThing 
{ 
private: 
    void swap() { 
     int c = a; 
     a = b; 
     b = c; 
    } 
public: 
    int a, b; 
    MyThing (int _a, int _b) : a(_a), b(_b) {} 
    int sum() 
    { 
     return a + b; 
    } 
}; 

然後換到圖1(圖2)

MyThing mt(1, 2); 

Sooooo,畢竟,我的問題是:是否有使用c樣式初始化列表(即他們更快?)創造的東西?或者它首先要做的就是:

struct MyThing 
{ 
    int a, b; 
    MyThing(int _a, int _b) : a(_a), b(_b) {} 
}; 

並且從頭開始使用它作爲圖2?是否有任何性能影響(即使它可忽略不計)?

謝謝!

+1

「是它們更快「 - 我會推薦使用任何最自然的方式,只有在真正遇到瓶頸時才更快地擔心。如果你在一個緊密的循環中執行此操作,那麼可能會有其他問題... – Flexo

+0

答案是「否」,它們沒有比正確的初始化列表更快。 –

+0

@Minging Duck--這就是我剛剛得出的結論 - 雖然使用簡寫來創建事物可以節省打字時間,但是當它們嵌套時(即嵌套的POD結構),讀取速度相當可怕 - 而且具有構造函數只有額外的輸入是類名(使用()而不是{}) - 更清晰,因爲發生了什麼:) 現在我同意awoodland - 如果它成爲一個問題,擔心性能;這不太可能,如果我擔心表現,我會創建許多不同的實例... 謝謝你的回答:) – Seb

回答

0

那麼,首先,你說的例子失敗了,其實是起作用的。 (直到添加構造函數纔會失敗)

現在請記住,一個對象只是一塊內存。因此的

MyThing mt = { 1, 2 };  // Fig A 

二進制圖像是完全一樣

int mt[2] = { 1, 2};   // Fig B. 

因此實現圖A或圖B,編譯器僅需要發射:

mt DW  0x0001  Fig C 
     DW  0x0002 

換句話說,零運行時間成本。

但是,如果ctor存在,那麼它必須運行(這是合同C++承諾的一部分)。 (不可避免地運行時成本)

類似地,私有成員,基類等,用來處理編譯時分配所需要的一對一的對應干擾,我們在圖C.

+0

然而,如果構造函數是MyThing(int x,int y):x_(x),y​​_(y){}'並且是內聯定義的,那麼不可能有任何運行時開銷。 –

+0

我不明白爲什麼私人會員有問題。爲什麼編譯器根據其可見性區分不同的成員?私有成員仍然有自己獨特的存儲空間,編譯器顯然知道編譯時的偏移量。我並不擔心性能,我只是想更好地理解語言/編譯器:) – Voo

+0

謝謝,我已經更新了示例,以便它*會*使編譯器失敗:) – Seb

0

使用c樣式初始化列表(即他們更快?)創造的東西是否有任何好處?

更快,更慢,它真的很重要嗎?它通常在語法上比調用構造函數更方便。這是C++ 0x允許你爲所有對象使用這種語法的原因的一部分。

作爲編譯時優化,聚合初始化可能是免費的。編譯器也可以優化簡單的構造函數。要知道的唯一方法是查看生成的程序集。但除非你有實際的瓶頸,否則你不應該在意。