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
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.
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
.
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.
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
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.
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
来源:https://stackoverflow.com/questions/5116541/difference-between-creating-object-with-or-without