使用()创建对象与不使用()创建对象的区别

发布于 2024-10-19 11:16:13 字数 575 浏览 2 评论 0原文

遇到了问题

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

┼── 2024-10-26 11:16:13

其他答案正确地指出括号版本实际上是函数声明。为了直观地理解它,假设您编写了 MainGUIWindow f(); 看起来更像是一个函数,不是吗? :)
之间有什么区别

MainGUIWindow* p = new MainGUIWindow;

更有趣的问题是和

MainGUIWindow* p = new MainGUIWindow();

带括号的版本称为值初始化,而不带括号的版本称为默认初始化。对于非 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

MainGUIWindow* p = new MainGUIWindow;

and

MainGUIWindow* p = new MainGUIWindow();

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.

烦人精 2024-10-26 11:16:13

以下内容:

MainGUIWindow myWindow();

声明一个不带参数并返回 MainGUIWindow 的函数。即 myWindow 是一个函数名称。

MainGUIWindow myWindow;

另一方面创建一个 MainGUIWindow 类型的对象 myWindow

The following:

MainGUIWindow myWindow();

declares a function that takes no arguments and returns MainGUIWindow. I.e. myWindow is a function name.

MainGUIWindow myWindow;

on the other hand creates an object myWindow of type MainGUIWindow.

原谅过去的我 2024-10-26 11:16:13

不同之处在于,它

MainGUIWindow myWindow(); 

声明了函数 myWindow,它不带参数并返回 MainGUIWindow,而

MainGUIWindow myWindow; 

创建 MainGUIWindow 类型的新对象,调用它的默认构造函数。

The difference is, that

MainGUIWindow myWindow(); 

declares function myWindow, which takes no parameters and returns MainGUIWindow, whereas

MainGUIWindow myWindow; 

creates new object of type MainGUIWindow, calling it's default constructor.

强者自强 2024-10-26 11:16:13

从你所描述的情况来看,不存在任何实际问题。您删除括号并宾果游戏!有用。

当它采用单个参数并且您想传入一个临时参数时,“最令人烦恼的解析”是一个更大的问题,例如

class Foo
{
public:
 explicit Foo( const Bar& bar );
};

Foo foo( Bar() );

不会创建 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

class Foo
{
public:
 explicit Foo( const Bar& bar );
};

Foo foo( Bar() );

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.

泪眸﹌ 2024-10-26 11:16:13

为了解决代码歧义,C++ 编译器的指导原则之一是:当某物可以是函数声明时,它就是函数声明。因此,当编译器看到:

MainGUIWindow myWindow();

它理解您正在声明一个名为 myWindow 的函数,该函数不带任何参数并返回 MainGUIWindow。显然这不是你想要的。

只要去掉括号就可以了:

MainGUIWindow myWindow; // Create an object called myWindow, of type 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:

MainGUIWindow myWindow();

It understands you are declaring a function called myWindow, that takes no parameters and returns a MainGUIWindow. Obviously this is not what you want.

Just remove the parenthesis and you will be fine:

MainGUIWindow myWindow; // Create an object called myWindow, of type MainGUIWindow
jJeQQOZ5 2024-10-26 11:16:13

在 C++ 中,每个看起来像函数声明的表达式都是函数的声明。考虑您问题中更复杂的示例:

#include <iostream>

struct X
{
  X( int value ) : x(value) {}
  int x;
};

struct Y
{
  Y( const X& x ) : y(x.x) {}
  int y;
};

int main()
{
  int test = 10;
  Y var( X(test) );                 // 1
  std::cout << var.y << std::endl;  // 2

  return 0;
}

乍一看,(1) 是局部变量 var 的声明,应使用类型 X 的临时变量进行初始化。但这看起来像是编译器的函数声明,并且您将在 (2) 中得到错误:

 error: request for member ‘y’ in ‘var’, which is of non-class type ‘Y(X)’

编译器认为 (1) 是名为 var 的函数:

Y                var(             X                     test            );
^- return value  ^-function name  ^-type of an argument ^-argument name

现在,如何对编译器说您不想声明函数吗?您可以使用额外的括号,如下所示:

Y var( (X(test)) );  

在您的情况下,编译器的 MainGUIWindow myWindow() 看起来像函数声明:

MainGUIWindow    myWindow(        void                  )
^- return value  ^-function name  ^-type of an argument

In C++ every expression that looks like a function declaration is a declaration of a function. Consider more complex sample that in your question:

#include <iostream>

struct X
{
  X( int value ) : x(value) {}
  int x;
};

struct Y
{
  Y( const X& x ) : y(x.x) {}
  int y;
};

int main()
{
  int test = 10;
  Y var( X(test) );                 // 1
  std::cout << var.y << std::endl;  // 2

  return 0;
}

At first glance (1) is a declaration of the local variable var which should be initialized with a temporary of a type X. But this looks like a function declaration for a compiler and you will get an error in (2):

 error: request for member ‘y’ in ‘var’, which is of non-class type ‘Y(X)’

The compiler considers that (1) is the function with name var:

Y                var(             X                     test            );
^- return value  ^-function name  ^-type of an argument ^-argument name

Now, how to say to the compiler that you do not want to declare a function? You could use additional parentheses as follows:

Y var( (X(test)) );  

In your case MainGUIWindow myWindow() for the compiler looks like function declaration:

MainGUIWindow    myWindow(        void                  )
^- return value  ^-function name  ^-type of an argument
朮生 2024-10-26 11:16:13

另外,来自 CppCon 2017:Louis Brandy “Curiously Recurring C++ Bugs at Facebook”

std::unique_lock<std::mutex> (_mutex);

是一个名为“_mutex”的锁的声明,该锁不锁定任何内容。由于您通常不需要稍后与锁进行交互,因此很容易忘记给它命名。

对于任何同时具有默认构造函数和采用一个参数的更有用的构造函数的 RAII 对象来说,这都是一个问题。

Also, from CppCon 2017: Louis Brandy “Curiously Recurring C++ Bugs at Facebook”

std::unique_lock<std::mutex> (_mutex);

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文