openrecordset from ejemplos ejemplo data currentdb c++ qt most-vexing-parse

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