2017-10-05 131 views
1

的方法之間的差異請考慮構造的對象的3種方式:什麼是構造物體

1)

LogTreeItem::LogTreeItem(const QList<QVariant>& data, LogTreeItem* parent) : 
    m_parentItem {parent}, m_itemData {data} 
{ 
} 

2)

LogTreeItem::LogTreeItem(const QList<QVariant>& data, LogTreeItem* parent) : 
    m_parentItem (parent), m_itemData (data) 
{ 
} 

3 )

TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent) 
{ 
    m_parentItem = parent; 
    m_itemData = data; 
} 

它們100%相等嗎?如果不是,他們在哪裏有區別?每種方法有哪些優勢/劣勢?

我猜測的拷貝賦值一些東西,移動的構造函數或現代C++ 11及以後的一些先進的東西在1例和2

回答

6

第一個和第二個對大多數類型都會做同樣的事情。但是,對於具有接受std::initializer_list的構造函數的類型,第一個將更喜歡這個,第二個將更喜歡普通的構造函數。典型的例子是帶有兩個參數的std::vector - 它們是放入矢量的兩個項目,還是一個重複計數的項目。

第三個版本根本不控制結構。正如Mateusz正確指出的,默認構造函數用於創建對象,然後通過賦值提供值。在許多類型中,一些參數只能在施工過程中設置,在賦值過程中不能更改,並且此方法根本不起作用。還要考慮必須在施工時綁定的引用和const成員,這些成員必須用其最終值構造,因爲分配已禁用。

+3

第一個構造函數在沒有初始化列表的情況下會使用列表初始化,這將防止任何縮小轉換 - 如果成員的類型比參數 –

+1

更窄,則將無法編譯儘管用戶沒有提到它,在沒有收到任何參數的情況下討論()vs {}可能會有所幫助,因爲這對於聚合類型和基元是非常重要的區別。 –

+1

@NirFriedman:至少在ctor-initializer列表中,'x {}'和'x()'都會導致值初始化。也許你正在考慮語句,其中'X x {};'是帶有支撐初始值設定項的對象聲明,但是'X x();'是一個函數聲明? –

4

在第三個例子着手完成,首先創建成員與默認的構造函數,然後複製分配。