tipos sirve que por para defecto copia constructores c++ constructor default-constructor c++-faq most-vexing-parse

c++ - por - para que sirve un constructor en c#



Constructor por defecto con paréntesis vacíos (9)

Como dijeron los demás, es una declaración de función. Desde C ++ 11 puede usar la inicialización de llaves si necesita ver algo vacío que explícitamente le dice que se usa un constructor predeterminado.

Jedi luke{}; //default constructor

¿Hay alguna buena razón para que un conjunto vacío de corchetes (paréntesis) no sea válido para llamar al constructor predeterminado en C ++?

MyObject object; // ok - default ctor MyObject object(blah); // ok MyObject object(); // error

Parece que escribo "()" automáticamente cada vez. ¿Hay alguna buena razón por la que esto no está permitido?


Como se mencionó muchas veces, es una declaración. Es así para la compatibilidad con versiones anteriores. Una de las muchas áreas de C ++ que son tontas / inconsistentes / dolorosas / falsas debido a su legado.


Desde n4296 [dcl.init]:

[ Nota:
Dado que () no está permitido por la sintaxis para el inicializador , X a(); no es la declaración de un objeto de clase X, sino la declaración de una función que no toma ningún argumento y devuelve una X. La forma () está permitida en otros contextos de inicialización (5.3.4, 5.2.3, 12.6.2).
-finalizar nota]


La misma sintaxis se utiliza para la declaración de funciones, por ejemplo, el object función, no toma ningún parámetro y devuelve MyObject


Porque el compilador cree que es una declaración de una función que no toma argumentos y devuelve una instancia de MyObject.


Porque se trata como la declaración de una función:

int MyFunction(); // clearly a function MyObject object(); // also a function declaration


Supongo que el compilador no sabría si esta afirmación:

Objeto MyObject ();

es una llamada de constructor o un prototipo de función que declara una función llamada objeto con tipo de retorno MyObject y sin parámetros.


También podría usar la forma más detallada de construcción:

MyObject object1 = MyObject(); MyObject object2 = MyObject(object1);

En C ++ 0x esto también permite auto :

auto object1 = MyObject(); auto object2 = MyObject(object1);


Más molesto análisis

Esto está relacionado con lo que se conoce como "análisis más irritante de C ++". Básicamente, cualquier cosa que pueda interpretar el compilador como una declaración de función se interpretará como una declaración de función.

Otra instancia del mismo problema:

std::ifstream ifs("file.txt"); std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());

v se interpreta como una declaración de función con 2 parámetros.

La solución alternativa es agregar otro par de paréntesis:

std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());

O bien, si tiene disponible C ++ 11 y la inicialización de la lista (también conocida como inicialización uniforme):

std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};

Con esto, no hay forma de que pueda ser interpretado como una declaración de función.