2017-06-26 75 views
2

假設我有以下結構:在C++類似Java的默認構造函數的含義

struct A { 
    A() { cout << "Default ctor\n"; } 

    A(int) { cout << "Ctor with params\n"; } 
}; 

然後我想創建一個對象。在Java中,我習慣了,當我創建一個對象來使用括號,所以第一個願望是寫類似的東西:

A a(); 

代碼編譯,但實際上a不是A一個實例,它是不同的。

所以問題是:什麼是a,爲什麼我應該省略括號來調用默認構造函數?

回答

3

the most vexing parse什麼你實際上正在聲明一個函數。爲緩解這一問題的方法是要麼消除()或使用C++ 11統一初始化語法,

A a; 
A a{}; 
+0

這是**而不是**「最令人頭疼的解析」;看看你鏈接到的頁面上的例子。它只是一個函數聲明。最令人頭痛的解析是非常微妙的,這就是爲什麼它令人煩惱。 –

+0

@PeteBecker clang似乎認爲這是最令人頭痛的解析(雖然gcc不),請參閱https://wandbox.org/permlink/jLNCBAxm6txCyeAf。而且我也這樣做了,維基百科頁面中的第一個例子只是另一個相同的複雜版本,最令人頭疼的解析來自這樣的事實:C++標準要求這樣的表達式被視爲函數聲明,而程序員可能意味着它是一個變量聲明和初始化。在這種情況下,編譯器應警告您可能錯誤。因此,vex。 – Curious

+0

「第一個例子只是另一個複雜的版本......」 - 完全是。你不會在該頁面上找到**這個簡單的代碼**,因爲它不是最令人頭疼的解析。最令人煩惱的解析是非常微妙的。當然,這個術語有可能成爲一種意味着「這是我不明白的東西,所以我很煩惱」,但這不是它的原始含義,也不是它在頁面上給出的含義。 –

2

在C++中,A a();函數稱爲a不帶參數,並返回一個A向前聲明。它確實使用默認構造函數而不是創建A的實例。

在Java中,沒有必要的功能向前聲明,所以A a();可以閱讀等同於A a;

的C這種好奇++甚至有一個名字:看https://en.wikipedia.org/wiki/Most_vexing_parse

+0

這是** **不是「最棘手的解析」。你鏈接的頁面顯示最令人頭痛的解析的例子,而這個不在那裏。 –