2014-02-27 102 views
2
struct ListNode { 
    int val; 
    ListNode *next; 
    ListNode(int x) : val(x), next(nullptr) { } 
}; 

這是ListNode的定義。 ListNode dummy{-1, head};是什麼意思?什麼是「ListNode dummy {-1,head};」意思?

+2

這不應該編譯。 'ListNode'不是一個聚集(它有一個用戶提供的構造函數),所以'dummy'不能使用聚合初始化來初始化,並且它沒有帶兩個參數的構造函數。 – chris

+0

不,不是。 'ListNode'有一個用戶提供的構造函數,所以它不是一個聚合,也不具備聚合初始化的資格。此外,它沒有初始化列表構造函數,也沒有可以接受兩個參數的構造函數。 – Brian

+0

@nneonneo不,它不是。 – Borgleader

回答

4

這就是列表初始化,這是一種用於初始化C++ 11中引入的對象的相當新的語法。

在這種情況下,這是一個錯誤。由於該類有用戶提供的構造函數,因此只能使用構造函數進行初始化;這個初始化需要一個構造函數,它帶有兩個不存在的參數。如果有一個合適的構造,就像

ListNode(int val, ListNode* next) : val(val), next(next) { } 

那就用它來初始化對象,傳遞的價值觀-1head作爲構造函數的參數。

如果類沒有聲明構造函數(或只是聲明刪除或默認的),使之成爲一個,那麼這將執行聚合初始化,初始化第一個成員val-1,和第二構件nexthead。但它不是一個聚合,所以這不會發生。

+0

如果編譯的話,我假定在這種情況下,使用的特定編譯器允許類似於聚合初始化的東西,作爲語言的擴展。 (只要它發出警告,這樣做是合法的。) – Brian

+0

我對於這種迂腐行爲感覺不好,但是構造函數是'ListNode()= default;',它可以在不使用構造函數的情況下被初始化。此構造函數不是用戶提供的,因此可以使用聚合初始化,並且聚合初始化不使用構造函數。 – chris

+0

@chris:確實。我已經讓這門語言變得更具學生友好性,希望不會混淆含義太多。 –

1

此施工句式

ListNode dummy{-1, head}; 

定義了名稱虛設類型ListNode的對象,並利用支撐初始化列表作爲初始值設定。

編譯器搜索具有兩個參數的類構造函數,類定義中沒有這樣的構造函數只有構造函數具有一個參數。所以編譯器會發出一個錯誤,它沒有找到合適的構造函數。

我想你alread看到下面的結構

int a[] = { 1, 2, 3 }; 

其實這種結構

ListNode dummy{-1, head}; 

是一樣的。你可以把它寫成

ListNode dummy = {-1, head}; 

不同的是,類ListNode具有用戶定義的構造和作爲結果,編譯器會尋找一個合適的構造函數與類兩個參數。

如果類有構造

ListNode(int x, ListNode *node = nullptr) : val(x), next(node) { } 

代替

ListNode(int x) : val(x), next(nullptr) { } 

那麼代碼片段將被successfuly編譯,因爲這個修改的構造函數被調用。