2012-12-29 25 views
1

可能重複:
Initializing fields in constructor - initializer list vs constructor body對於類構造函數,通過圓括號或等號分配的區別是什麼?

在講座中,我參加了,講師在C++簡單談及了非默認的類的構造函數。他特別指出,一種版本比另一種更可取。他表現出這兩個例子:

Point::Point(double x, double y, double z) 
: x_(x), y_(y), z_(z) 
{} 

Point::Point(double x, double y, double z) 
{ x_= x; y_= y; z_= z; } 

他提到的第一實施例(使用括號內)是寫構造方法的優選方式。

我的問題是:有什麼區別,爲什麼這很重要?第一個優於第二個的方式是什麼?

+0

第一種方法避免了在某些情況下的初始化和賦值,它是唯一一個可以用於const和引用成員的函數。第一個也可以提供對基類的初始化和委託構造函數的訪問。 – chris

+0

http://stackoverflow.com/questions/9903248/initializing-fields-in-constructor-initializer-list-vs-constructor-body和http://stackoverflow.com/questions/1598967/benefits-of-initialization-lists回答這個。 – jogojapan

回答

3

的原因是,首先是的分配,這是一個初始化,而第二代碼實際上是相同的:

Point::Point(double x, double y, double z) 
: x_(), y_(), z_() 
{ x_= x; y_= y; z_= z; } 

也就是說,所有成員都默認初始化這裏是前分配。當它們的類型沒有默認構造函數時,這不起作用。例如:

class Foo { 
    Foo(); // Private, undefined constructor 
public: 
    Foo(int) { } 
}; 

class Bar { 
    int& i; 
    Foo f; 

public: 
    Bar() { i = 0; f = Foo(0); } 
}; 

此代碼不會起作用,因爲Bar的構造函數依賴於對f默認構造函數和初始化劑存在於i,這兩者都不存在。

但即使所有成員都是默認構造的或可初始化的,仍然建議在初始化列表中初始化它們,而不是通過構造函數中的賦值:如果沒有其他,它會更有效率(因爲否則您將執行冗餘在某些情況下可能會付出代價的操作)。

2

第一個副本 - 在輸入構造函數體之前構造成員。注意:這是C++中所謂的構造函數初始化程序列表的較大主題的一部分。對於在初始化程序列表中表示的某些成員變量類型,其中包括引用成員,具有非默認構造的成員(即需要其構造函數的參數)和const成員,它是強制。在問題中提出的情況下的用法是調用copy-constuction,而不是默認構造,然後是in-body assignment,這會使我們...

第二個默認值 - 構造成員之前的成員構造函數體被輸入,然後在體內分配它們的值。這對於支持默認構造的成員纔是可行的。

在這兩者中,第一個通常是首選,特別是對於具有昂貴的默認初始化的複雜數據類型。由於即將進行的分配,所述初始化將可能部分或完全被浪費。您通常會更好地使用複製結構,而不是使用複製結構。注:全部內部數據類型(int,float,指針等)支持拷貝構造。

0

第二種方法執行默認構造,然後執行分配。

如果默認的構造函數不可用,它將無法工作,並且無論如何它可能不便宜。

此外,第一個方法可以調用顯式構造函數,而第二個方法不可以調用顯式構造函數。

相關問題