c++ - from - Diferencia entre crear objeto con() o sin
recordset vba excel (6)
El seguimiento:
MainGUIWindow myWindow();
declara una función que no toma argumentos y devuelve MainGUIWindow
. Es decir myWindow
es un nombre de función.
MainGUIWindow myWindow;
por otro lado crea un objeto myWindow
de tipo MainGUIWindow
.
acabo de encontrarme con el problema
error: request for member ‘show’ in ‘myWindow’, which is of non-class type ‘MainGUIWindow()’
Al intentar compilar una aplicación qt simple:
#include <QApplication>
#include "gui/MainGUIWindow.h"
int main( int argc, char** argv )
{
QApplication app( argc, argv );
MainGUIWindow myWindow();
myWindow.show();
return app.exec();
}
Resolví esto reemplazando
MainGUIWindow myWindow();
por
MainGUIWindow myWindow;
pero no entiendo la diferencia Mi pregunta: ¿Cuál es la diferencia?
Saludos, Dirk
En C ++, cada expresión que se parece a una declaración de función es una declaración de una función. Considera una muestra más compleja que en tu pregunta:
#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;
}
A primera vista (1) es una declaración de la variable local var
que debe inicializarse con un temporal de un tipo X
Pero esto parece una declaración de función para un compilador y obtendrá un error en (2):
error: request for member ‘y’ in ‘var’, which is of non-class type ‘Y(X)’
El compilador considera que (1) es la función con el nombre var
:
Y var( X test );
^- return value ^-function name ^-type of an argument ^-argument name
Ahora, ¿cómo decirle al compilador que no desea declarar una función? Podría usar paréntesis adicionales de la siguiente manera:
Y var( (X(test)) );
En su caso, MainGUIWindow myWindow()
para el compilador se parece a la declaración de función:
MainGUIWindow myWindow( void )
^- return value ^-function name ^-type of an argument
La diferencia es que
MainGUIWindow myWindow();
declara la función myWindow
, que no toma parámetros y devuelve MainGUIWindow
, mientras que
MainGUIWindow myWindow;
crea un nuevo objeto de tipo MainGUIWindow
, llamando a su constructor predeterminado.
Las otras respuestas declaran correctamente que la versión de paréntesis es en realidad una declaración de función. Para entenderlo de forma intuitiva, suponga que escribió MainGUIWindow f();
Se parece más a una función, ¿no es así? :) La pregunta más interesante es cuál es la diferencia entre
MainGIUWindow* p = new MainGIUWindow;
y
MainGIUWindow* p = new MainGIUWindow();
La versión con paréntesis se llama inicialización de valor, mientras que la versión sin se llama inicialización predeterminada. Para las clases que no son POD no hay diferencia entre los dos. Sin embargo, para las estructuras POD, las inicios de inicialización de valores establecen a todos los miembros en 0,
my2c
Adición: en general, si alguna construcción sintáctica puede interpretarse como una declaración y otra cosa, el compilador siempre resuelve la ambigüedad a favor de la declaración .
No hay problemas reales con la situación que ha descrito. Quitas los paréntesis y el bingo! funciona.
El "análisis más desconcertante" es un problema mucho más grande cuando toma un solo parámetro y usted quiere pasar un temporal, por ejemplo
class Foo
{
public:
explicit Foo( const Bar& bar );
};
Foo foo( Bar() );
no creará una instancia de un Foo, pero también declarará una función que toma un puntero a la función, y esta realmente te pica a menudo.
Una de las pautas para los compiladores de C ++, para resolver ambigüedades de código, es: cuando algo puede ser una declaración de función, es una declaración de función. Entonces cuando el compilador ve:
MainGUIWindow myWindow();
Entiende que está declarando una función llamada myWindow
, que no toma parámetros y devuelve una MainGUIWindow
. Obviamente esto no es lo que quieres.
Simplemente quita el paréntesis y estarás bien:
MainGUIWindow myWindow; // Create an object called myWindow, of type MainGUIWindow