2010-02-23 94 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 ]

相关问题