the steps program plus orwell oficial guide first dev descargar blog basics c++ class function-declaration variable-initialization

steps - structure of c++



¿Cómo es posible usar esto en c++? (5)

Cuando escribes a a1(); en realidad se está analizando como una declaración de función, no como una llamada al constructor predeterminado.

a a1;

llamará al constructor predeterminado correctamente

Cuando escribas aa; funciona porque el nombre de la variable tiene preferencia sobre el nombre de la clase en lo que se denomina ocultación del nombre, pero aunque funcione solo generará confusión y evitaría hacerlo.

Y para todas aquellas personas a las que les gustan los estándares, aquí van.

Un nombre de clase (9.1) o un nombre de enumeración (7.2) puede estar oculto por el nombre de una variable, miembro de datos, función o enumerador declarado en el mismo ámbito. Si una clase o nombre de enumeración y una variable, miembro de datos, función o enumerador se declaran en el mismo ámbito (en cualquier orden) con el mismo nombre, la clase o el nombre de enumeración se ocultan donde sea que la variable, miembro de datos, función o el nombre del enumerador es visible.

  1. Para mi sorpresa, encontré que el nombre de un objeto c ++ puede ser el mismo que el nombre de la clase. ¿Puede alguien explicarme la razón por la cual?
  2. Cuando declaro un objeto de la clase a como a a1() , no genera un error, pero no llama al constructor. ¿Por qué está pasando esto?

Mi código:

#include<iostream> using namespace std; class a { public: a() { cout << "in a/n"; } }; int main() { a a1(); a a; }


Es válido ocultar el nombre de una clase con una variable, de hecho, si nos fijamos en el borrador de la sección 3.3.10 C ++, el párrafo 2 oculta el nombre ( énfasis mío ):

Un nombre de clase (9.1) o un nombre de enumeración (7.2) puede estar oculto por el nombre de una variable , miembro de datos, función o enumerador declarado en el mismo ámbito. Si una clase o nombre de enumeración y una variable, miembro de datos, función o enumerador se declaran en el mismo ámbito (en cualquier orden) con el mismo nombre, la clase o el nombre de enumeración se ocultan donde sea que la variable, miembro de datos, función o el nombre del enumerador es visible.

No creo que sea una buena práctica y conduciría a un código difícil de mantener. Esta línea de código en realidad está declarando una función:

a a1();

alternativamente puedes usar este pre- C ++ 11 :

a a1 ;

Inicialización uniforme o introducida en C ++ 11 :

a a1{} ;

Dando vueltas para ocultar el nombre , me sorprendió gratamente que clang te advirtiera sobre esto con este código, independientemente de los niveles de advertencia establecidos:

int main() { a a; a a2 ; }

Recibo este mensaje:

main.cpp:12:10: note: class ''a'' is hidden by a non-type declaration of ''a'' here a a; ^

aunque no puedo ver para obtener una advertencia similar de gcc .

Actualizar

Al pensar en estos comentarios que hice anteriormente sobre las verrugas de la inicialización uniforme , me di cuenta de que si hubiera sospechado que a1 era del tipo correcto, podría haber usado typeid para depurar lo que estaba sucediendo. Por ejemplo este código:

std::cout << typeid(a).name() << std::endl ; std::cout << typeid(a1).name() << std::endl ;

resultados en esta salida en Coliru ejemplo vivo :

1a F1avE

y pasándolo a través de c++filt recibes esta salida:

a () // A function that returns type a a // type a


Esto es lo que obtuve de tu código cuando intenté compilarlo con un clang , creo que lo dice todo.

test.cpp:15:9: warning: empty parentheses interpreted as a function declaration [-Wvexing-parse] a a1(); ^~ test.cpp:15:9: note: remove parentheses to declare a variable a a1(); ^~ 1 warning generated.


a a1(); Es una declaración de función.

Esa es una razón importante para la creación de una inicialización uniforme en C ++ 11. Para inicializar el objeto utilizando el constructor en C ++ 11, use a a1{};


a a1(); es un tipo de devolución de declaración de función que no tiene nada que ver con el constructor que llama

aa ; Es simple declaración funciona bien llamará el constructor