2012-01-18 62 views
8

最近,我從很受歡迎的C++ FAQ讀了很多關於構造函數。其中一個條目提到最好使用初始化列表,而不是在構造函數本身的代碼塊中初始化類成員。正在初始化非指針類成員

這是因爲編譯器傾向於創建類成員的多個副本,而不是簡單的一個副本。

良好

Foo::Foo(void) 
    : mBar(new Bar) //pointer to some memory address 
{ 
} 

Foo::Foo(void) 
{ 
    mBar = new Bar; 
} 

一件事它還規定(和,而這涉及到構造函數,它也涉及純屬的初始化對象從甚至非成員函數升)是通過初始化方法的對象時,如以下:

void f(void) 
{ 
    Foo foo(Bar()); //Bad. 

    foo.x(); //error 
} 

你會的,我引述:"[declare] a non-member function that returns a Foo object"

(更多信息,請點擊上面的鏈接)

問題

正因爲如此,是不明智的有以下幾種:

甚至這樣的:

Geometry::Geometry(void) 
    : mFaces(QVector<GLushort>), 
     mFinalized(false), 
     mNormals(QVector<QVector3D>), 
     mVerticies(QVector<QVector3D>) 

由於t hese被分配(即,這些是非指針的事實),這讓我懷疑這些對象是否在開始時甚至需要初始化。如果他們這樣做,這是否是正確的方法?或者,有沒有更好的初始化方法?

如何這涉及到的問題

這涉及到的一般問題,由於背後C++的構造函數初始化的方法使用構造函數,隨着事實,我懵了涉及到兩個初始化對象的方式無論是否分配在堆棧上的對象 - 或者,所以我相信 - (無論哪種方式,沒有指針分配的對象),即使需要初始化。

回答

12

如果成員變量是具有用戶聲明的默認構造函數的類類型,則不需要在初始化列表中明確地提及它:其構造函數的默認構造函數將在構造過程中,在構造函數構造函數被輸入。

如果成員變量是一個基本類型(如intbool),或者是不具有任何用戶聲明的構造函數的類類型的,你需要明確地初始化它,否則它不會被初始化(和它將有一個未知的值;你不能讀未初始化的對象)。

+0

那麼,這是否意味着,根據上面的代碼,我只是創建了我分配的對象的多個副本? – zeboidlund 2012-01-18 23:24:44

+3

當你使用mFaces(QVector < GLushort >())''時,你構造一個臨時的'QVector ',從那個臨時對象中拷貝構造'mFaces',然後銷燬那個臨時對象。所以,是的,你正在創造比必要的更多的物體。 – 2012-01-18 23:27:06