Difference between creating object with () or without

喜你入骨 提交于 2019-11-27 11:36:37
Armen Tsirunyan

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!