我正在使用 g++ 在 Cygwin 中编译一个 C++ 程序,我有一个类的构造函数没有参数。我有台词:
MyClass myObj();
myObj.function1();
在尝试编译它时,我收到消息:
error: request for member 'function1' in 'myObj', which is of non-class type 'MyClass ()()'
经过一番研究,我发现解决方法是将第一行更改为
MyClass myObj;
我可以发誓我以前在 C++ 中做过带括号的空构造函数声明。这可能是我正在使用的编译器的限制,还是语言标准真的说不要对没有参数的构造函数使用括号?
尽管
MyClass myObj();
可以被解析为具有空初始值设定项或函数声明的对象定义,但语言标准指定歧义始终以有利于函数声明的方式解决。在其他上下文中允许使用空括号初始值设定项,例如在 new
表达式中或构造一个 value-initialized temporary.
这被称为Most Vexing Parse问题。当解析器看到
MyClass myObj();
它认为你正在声明一个名为
myObj
的函数,它没有参数并返回一个MyClass
。
要绕过它,请使用:
MyClass myObj;
我在 C++ 标准(§8.5.8)中找到了这个:
初始化器为空括号集的对象,即 (),应进行值初始化。
[注:因为 () 是不允许的 初始化程序的语法,
X a ();
不是 X 类对象的声明,而是 不带参数的函数声明 参数并返回一个 X. 形式 () 在某些其他情况下是允许的 初始化上下文(5.3.4、5.2.3、 12.6.2). ——尾注]
这是一个众所周知的问题,与编译器无关。本质上,您是在声明一个返回类型 MyObj 的函数。毫不奇怪,您不能调用它的构造函数。请参阅 C++ faq lite 以获得很好的解释。
MyClass myObj();
这被解析为函数声明。该函数称为 myObj,不带参数并返回一个 MyClass 对象。我从未见过编译器接受它。另一方面,
MyClass* myPtr = new MyClass();
是可以接受的,这可能让您感到困惑吗?
你的行让编译器认为你正在声明一个名为
myObj
的函数,它不接受任何参数并返回一个MyClass
。这种歧义解析确实很烦人
标准不需要括号。
int* x = new int;
是合法语法。
在你的例子中
myclass myobj();
是一个函数原型。而myclass myobj;
是一个变量。