2016-03-12 45 views
1

在許多文章和書籍中提出了許多C++編程最佳實踐。以下是與C++類數據成員相關的子集:應該在使用之前初始化C++類的Qt類數據成員嗎?

  1. 確保對象在使用前被初始化。
  2. 確保所有構造函數初始化對象中的所有內容。
  3. 在每個構造函數的初始化程序列表中初始化數據成員通常比在其正文中更有效。
  4. 在初始化程序列表中,數據成員應按照它們聲明的順序列出。

考慮下面的類使用Qt類類型的數據成員:

class MyClass { 
public: 
    myClass(); 
    ~myClass(); 
private: 
    int myInt; 
    QString myQString; 
    QList<QString> myQList; 
    QHash<int, QString> myQHash; 
    char * pChar; 
}; 

通過應用上述最佳實踐,構造函數代碼將如下所示:

MyClass::MyClass() : 
    myInt(0), // OK, primitive should be initialized. 
    myQString(), // Is this really needed? 
    myQList(),  // Is this really needed? 
    myQHash(), // Is this really needed? 
    pChar(NULL) // OK, pointer should be initialized. 
{ 
} 

然而,我有一個印象,並不是所有的Qt類數據成員都需要初始化。但我不是100%肯定的。一些開發人員爭辯說,通過將所有數據成員放入初始化列表中,我們可以避免忽略應初始化的一些重要數據成員的初始化。但是,如果這是一個真正的問題,我寧願把一個註釋行對於不需要初始化每個數據成員,例如:

​​

總之,我想知道一個Qt類時數據成員應該被初始化,並且當不需要初始化時,以及爲什麼。謝謝!

+0

我忘了提及,對於類MyClass中涉及的所有Qt類,我們可以假定它們有一個可用的0參數構造函數。也就是說,'QString :: QString()','QList :: QList()'和'QHash :: QHash()'是可用的。有了這個假設,原來的問題可能會導致另外兩個問題: 問題1:MyClass :: MyClass()的兩個版本是否等同?也就是說,他們是否產生了2個相同內容的對象? Q2:一個版本比另一個更快嗎? – jonathanzh

回答

5

如果您沒有默認的類構造函數,那麼您必須在初始化程序列表中初始化它,並且不需要在初始化程序列表中調用默認構造函數。這不是Qt的具體規定,它是任何類別的通用規則。當你有一個默認的構造函數(它接受0參數)時,即使你不在初始化列表中調用它,它也會自動調用。

更新:

Q1:以上是相當於2個版本MyClass的MyClass的::()的? 是,他們是否產生2個相同內容的對象?

是的。

問題2:一個版本比另一個更快嗎?

您可以更快地輸入第二個版本;-),沒有性能差異。

+0

我對你答案的理解是:如果'myQString(),'行沒有被顯式地放在初始化列表中,編譯器會隱式地調用'QString'的0參數構造函數。所以上面兩個版本的'MyClass :: MyClass()'將產生2個相同內容的對象,並且花費相似的時間。所以兩個版本都不錯,但是第一版可能更好。我的理解是否正確?謝謝! – jonathanzh

+0

我更喜歡DRY(不要重複自己)如果編譯器代表您做同樣的事情,那麼您爲什麼要自己編寫它,我更喜歡第二個版本,因爲您可以獲得訂單警告並解決警告您將花費時間查看頭文件中數據成員的順序。 –

+0

感謝您的確認。由於這兩個版本是相同的,我更喜歡第一版。只要代碼更容易理解並由其他開發人員維護,我不介意寫一些額外的代碼行 - 但這是我個人的偏好。如果我是全班唯一的開發者,我也會像你一樣選擇第二個版本 – jonathanzh

0

無論你明確地調用它,QObject的默認構造函數都會被調用,或者當你的對象被創建時它會被隱式調用。

您可能會將調試消息放入QObject構造函數代碼中,然後親自查看,爲真實起見,這是開源代碼!:)