2010-02-23 82 views
44

我正在使用g ++編譯Cygwin中的C++程序,並且我有一個構造函數沒有參數的類。我有臺詞:沒有參數的語言標準的構造函數沒有括號?

MyClass myObj(); 
myObj.function1(); 

,並試圖對其進行編譯的時候,我得到的消息:

錯誤:請在「MyObj中」,這是無級式的「成員「功能1」 MyClass的()()'

經過一番研究,我發現修復方法是將第一行更改爲 MyClass myObj;

我可以發誓我已經在C++中使用括號完成了空的構造函數聲明。這可能是我正在使用的編譯器的限制,還是語言標準真的說不使用不帶參數的構造函數的括號?

回答

49

雖然MyClass myObj();可以被解析爲一個空對象定義或者一個空函數聲明,但是語言標準指定了歧義總是被解析爲有利於函數聲明。在其他上下文中允許空的括號初始化器,例如在new表達式中或構造一個值初始化的臨時值。

1

該標準不需要括號。

int* x = new int; 

是合法的語法。

在你的情況下,myclass myobj();是一個函數原型。而myclass myobj;是一個變量。

3

您的行使編譯器認爲您正在聲明名爲myObj的函數,該函數不帶任何參數並返回MyClass。這種模棱兩可的決議確實令人討厭。

10

這是一個相當有名的問題,不依賴於編譯器。基本上,你在做的是聲明一個返回MyObj類型的函數。毫不奇怪,你不能調用它的構造函數。請參閱C++ faq lite以獲得很好的解釋

+0

擴大 - 這只是在某些情況下的問題。寫下「拋出myexceptionclass();」,例如,並沒有混淆。這種語言在Petes語境中是不明確的,但是對規則的歧義化(語言嚴格地說並不是真正含糊不清的原因)選擇了一種解釋。當然,消歧規則意味着語言並不是真正含糊不清 - 但解析專家反正說,所以我也被允許!很多語言中最常見的消歧規則是針對運算符的優先級和關聯性的--C和C++更加模糊,因此存在一些奇怪的問題。 – Steve314 2010-02-23 14:22:01

44

這被稱爲最令人頭痛的解析問題。當解析器看到

MyClass myObj(); 

它會認爲你只是聲明稱爲myObj函數沒有參數,並返回一個MyClass

要解決它,使用方法:這是解析爲函數聲明

MyClass myObj; 
+0

嗨,除了被分別分配在堆棧和堆上,「MyClass obj」和「MyClass * obj = new MyClass()」之間是否有區別? – SexyBeast 2015-01-11 19:38:24

+1

一些。第一個將'obj'聲明爲'MyClass'類型的對象,並且在作用域退出時自動釋放。第二個將'obj'聲明爲'MyClass *'類型的對象,必須手動釋放它,並在範圍退出後可用。 – 2015-01-12 20:39:12

+0

是的,這正是分別在堆棧和堆上分配的結果,對吧? – SexyBeast 2015-01-12 21:26:50

4
MyClass myObj(); 

,函數被調用MyObj中,不帶任何參數,並返回MyClass的對象。我從來沒有見過編譯器接受這一點。另一方面MyClass* myPtr = new MyClass();是可以接受的,可能會讓你感到困惑嗎?

18

我在C++標準(§8.5)中找到了這個。8):

An object whose initializer is an empty set of parentheses, i.e.,(), shall be value-initialized.

[Note: since() is not permitted by the syntax for initializer,

X a(); 

is not the declaration of an object of class X, but the declaration of a function taking no argument and returning an X. The form () is permitted in certain other initialization contexts (5.3.4, 5.2.3, 12.6.2). —end note ]