使用()创建对象与不使用()创建对象的区别
遇到了问题
error: request for member ‘show’ in ‘myWindow’, which is of non-class type ‘MainGUIWindow()’
我在尝试编译一个简单的 qt 应用程序时
#include <QApplication>
#include "gui/MainGUIWindow.h"
int main( int argc, char** argv )
{
QApplication app( argc, argv );
MainGUIWindow myWindow();
myWindow.show();
return app.exec();
}
:我通过替换来解决了这个问题
MainGUIWindow myWindow();
,
MainGUIWindow myWindow;
但我不明白其中的区别。我的问题:有什么区别?
问候, 短剑
i just run into the problem
error: request for member ‘show’ in ‘myWindow’, which is of non-class type ‘MainGUIWindow()’
when trying to compile a simple qt-application:
#include <QApplication>
#include "gui/MainGUIWindow.h"
int main( int argc, char** argv )
{
QApplication app( argc, argv );
MainGUIWindow myWindow();
myWindow.show();
return app.exec();
}
I solved this by replacing
MainGUIWindow myWindow();
by
MainGUIWindow myWindow;
but I don't understand the difference. My question: What is the difference?
Regards,
Dirk
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
其他答案正确地指出括号版本实际上是函数声明。为了直观地理解它,假设您编写了
MainGUIWindow f();
看起来更像是一个函数,不是吗? :)之间有什么区别
更有趣的问题是和
带括号的版本称为值初始化,而不带括号的版本称为默认初始化。对于非 POD 类,两者之间没有区别。然而,对于 POD 结构,值初始化涉及将所有成员设置为 0,
my2c
另外:一般来说,如果某个语法构造既可以解释为声明也可以解释为其他内容,则编译器总是会解决歧义赞成该声明。
The other answers correctly state that the parentheses version is actually a function declaration. To understand it intuitively, suppose you wrote
MainGUIWindow f();
Looks more like a function, doesn't it? :)The more interesting question is what is the difference between
and
The version with parentheses is called value-initialization, whereas the version without is called default-initialization. For non-POD classes there is no difference between the two. For POD-structs, however, value-initialization involves setting all members to 0,
my2c
Addition: In general, if some syntactic construct can be interpreted both as a declaration and something else, the compiler always resolves the ambiguity in favor of the declaration.
以下内容:
声明一个不带参数并返回
MainGUIWindow
的函数。即myWindow
是一个函数名称。另一方面创建一个
MainGUIWindow
类型的对象myWindow
。The following:
declares a function that takes no arguments and returns
MainGUIWindow
. I.e.myWindow
is a function name.on the other hand creates an object
myWindow
of typeMainGUIWindow
.不同之处在于,它
声明了函数
myWindow
,它不带参数并返回MainGUIWindow
,而创建
MainGUIWindow
类型的新对象,调用它的默认构造函数。The difference is, that
declares function
myWindow
, which takes no parameters and returnsMainGUIWindow
, whereascreates new object of type
MainGUIWindow
, calling it's default constructor.从你所描述的情况来看,不存在任何实际问题。您删除括号并宾果游戏!有用。
当它采用单个参数并且您想传入一个临时参数时,“最令人烦恼的解析”是一个更大的问题,例如
不会创建 Foo 的实例,但也会声明一个采用函数指针的函数,并且这一只确实经常蜇你。
There is no real problems with the situation you have described. You remove the parentheses and bingo! it works.
The "most vexing parse" is a much bigger issue when it takes a single parameter and you want to pass in a temporary, eg
will not create an instance of a Foo but will also declare a function that takes a function-pointer, and this one really does often sting you.
为了解决代码歧义,C++ 编译器的指导原则之一是:当某物可以是函数声明时,它就是函数声明。因此,当编译器看到:
它理解您正在声明一个名为
myWindow
的函数,该函数不带任何参数并返回MainGUIWindow
。显然这不是你想要的。只要去掉括号就可以了:
One of the guidelines for C++ compilers, in order to resolve code ambiguities, is: when something can be a function declaration, it is a function declaration. So when the compiler sees:
It understands you are declaring a function called
myWindow
, that takes no parameters and returns aMainGUIWindow
. Obviously this is not what you want.Just remove the parenthesis and you will be fine:
在 C++ 中,每个看起来像函数声明的表达式都是函数的声明。考虑您问题中更复杂的示例:
乍一看,(1) 是局部变量 var 的声明,应使用类型 X 的临时变量进行初始化。但这看起来像是编译器的函数声明,并且您将在 (2) 中得到错误:
编译器认为 (1) 是名为
var
的函数:现在,如何对编译器说您不想声明函数吗?您可以使用额外的括号,如下所示:
在您的情况下,编译器的
MainGUIWindow myWindow()
看起来像函数声明:In C++ every expression that looks like a function declaration is a declaration of a function. Consider more complex sample that in your question:
At first glance (1) is a declaration of the local variable
var
which should be initialized with a temporary of a typeX
. But this looks like a function declaration for a compiler and you will get an error in (2):The compiler considers that (1) is the function with name
var
:Now, how to say to the compiler that you do not want to declare a function? You could use additional parentheses as follows:
In your case
MainGUIWindow myWindow()
for the compiler looks like function declaration:另外,来自 CppCon 2017:Louis Brandy “Curiously Recurring C++ Bugs at Facebook”
是一个名为“_mutex”的锁的声明,该锁不锁定任何内容。由于您通常不需要稍后与锁进行交互,因此很容易忘记给它命名。
对于任何同时具有默认构造函数和采用一个参数的更有用的构造函数的 RAII 对象来说,这都是一个问题。
Also, from CppCon 2017: Louis Brandy “Curiously Recurring C++ Bugs at Facebook”
Is a declaration of a lock named "_mutex" that locks nothing. Since you typically don't need to interact with locks later, it's very easy to miss giving it a name.
This is a problem for any RAII object that has both a default constructor and a more useful constructor that takes one argument.