24

我只是遇到了问题

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;

但我不明白其中的区别。我的问题:有什么区别?

问候,德克

4

7 回答 7

49

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

MainGUIWindow* p = new MainGUIWindow;

MainGUIWindow* p = new MainGUIWindow();

带括号的版本称为值初始化,而没有括号的版本称为默认初始化。对于非 POD 类,两者之间没有区别。然而,对于 POD 结构,值初始化涉及将所有成员设置为 0,

my2c

补充:一般来说,如果某些句法构造既可以解释为声明,也可以解释为其他内容,编译器总是会解决歧义,支持声明

于 2011-02-25T11:23:38.880 回答
19

以下:

MainGUIWindow myWindow();

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

MainGUIWindow myWindow;

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

于 2011-02-25T11:19:20.520 回答
4

不同的是,那

MainGUIWindow myWindow(); 

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

MainGUIWindow myWindow; 

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

于 2011-02-25T11:20:07.107 回答
4

你所描述的情况没有真正的问题。你删除括号和宾果游戏!有用。

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

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

Foo foo( Bar() );

不会创建 Foo 的实例,但也会声明一个带有函数指针的函数,而这个函数确实经常刺痛你。

于 2011-02-25T11:52:19.013 回答
3

为了解决代码歧义,C++ 编译器的指导方针之一是:当某些东西可以是函数声明时,它就是函数声明。所以当编译器看到:

MainGUIWindow myWindow();

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

只需删除括号,你会没事的:

MainGUIWindow myWindow; // Create an object called myWindow, of type MainGUIWindow
于 2011-02-25T11:21:11.153 回答
0

在 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它应该用一个临时的 type 来初始化X。但这看起来像一个编译器的函数声明,你会在 (2) 中得到一个错误:

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

编译器认为 (1) 是具有 name 的函数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
于 2011-02-28T20:53:29.597 回答
-1

此外,来自 CppCon 2017:Louis Brandy “Curiously Recurring C++ Bugs at Facebook”</p>

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

是一个名为“_mutex”的锁的声明,它什么都不锁。由于您以后通常不需要与锁进行交互,因此很容易错过为其命名。

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

于 2020-08-06T22:15:31.697 回答