2010-02-23 9 views
44

Estaba compilando un programa C++ en Cygwin usando g ++ y tenía una clase cuyo constructor no tenía argumentos. Tenía las líneas:¿No hay paréntesis en un constructor sin argumentos, un estándar de lenguaje?

MyClass myObj(); 
myObj.function1(); 

Y cuando se trata de compilarlo, me dieron el mensaje:

error: solicitud de 'function1' miembro 'myObj', que es del tipo no-clase 'MiClase()() '

Después de investigar un poco, encontré que la solución era cambiar esa primera línea a MyClass myObj;

Podría jurar que he hecho declaraciones de constructores vacías con paréntesis en C++ antes. ¿Es esto probablemente una limitación del compilador que estoy usando o el estándar de lenguaje realmente dice que no use paréntesis para un constructor sin argumentos?

Respuesta

49

Aunque MyClass myObj(); se pudo analizar como una definición de objeto con un inicializador vacío o una declaración de función, el estándar de lenguaje especifica que la ambigüedad siempre se resuelve a favor de la declaración de la función. Se permite un inicializador de paréntesis vacío en otros contextos, p. en una expresión new o construyendo un value-initialized temporal.

1

La norma no requiere paréntesis.

int* x = new int; 

es la sintaxis legal.

En su caso myclass myobj(); es un prototipo de función. Mientras que myclass myobj; es una variable.

3

Su línea hace que el compilador crea que está declarando una función llamada myObj que no toma argumentos y devuelve MyClass. Esta resolución de ambigüedad es realmente molesta.

10

Este es un problema bastante conocido y no depende del compilador. Esencialmente, lo que estabas haciendo era declarar una función que retornaba tipo MyObj. No es sorprendente que no puedas llamar a su constructor. Consulte el C++ faq lite para obtener una buena explicación

+0

Expandir: solo es un problema en determinados contextos. Escribe "throw myexceptionclass();", por ejemplo, y no hay confusión. El lenguaje es ambiguo en el contexto de Petes, pero las reglas de desambiguación (la razón por la cual el lenguaje estrictamente no es realmente ambiguo) eligen una interpretación. Por supuesto, las reglas de desambiguación significan que el lenguaje no es realmente ambiguo, pero los expertos en análisis lo dicen de todos modos, ¡así que estoy autorizado! Las reglas de desambiguación más comunes en muchos idiomas son para la precedencia y la asociatividad del operador: C y C++ son mucho más ambiguos y, como resultado, hay algunos problemas extraños. – Steve314

44

Esto se conoce como el problema de análisis más molesto. Cuando el intérprete ve

MyClass myObj(); 

Se piensa que se está declarando una función llamada myObj que no tiene parámetros y devuelve un MyClass.

Para conseguir alrededor de él, utilice:

MyClass myObj; 
+0

Hola, aparte de ser asignado en la pila y el montón respectivamente, ¿hay alguna diferencia entre 'MyClass obj' y' MyClass * obj = new MyClass() '? – SexyBeast

+1

Algunos. El primero declara 'obj' como un objeto de tipo' MyClass', y se liberará automáticamente cuando el alcance salga. El segundo declara 'obj' como un objeto de tipo' MyClass * ', que debe ser liberado manualmente, y estará disponible después de que el alcance salga. –

+0

Sí, sí, eso es precisamente el resultado de ser asignado en la pila y montón, respectivamente, ¿verdad? – SexyBeast

4
MyClass myObj(); 

Eso es analizada como una declaración de la función, la función se llama myObj, no tiene argumentos y objeto devuelve MiClase. Nunca he visto un compilador que acepte eso. Por otro lado, MyClass* myPtr = new MyClass(); es aceptable, ¿puede ser que te haya confundido?

18

Encontré esto en el estándar C++ (§8.5.8):

An object whose initializer is an empty set of parentheses, i.e.,(), shall be value-initialized.

[Note: since() is not permitted by the syntax for initializer,

X a(); 

is not the declaration of an object of class X, but the declaration of a function taking no argument and returning an X. The form () is permitted in certain other initialization contexts (5.3.4, 5.2.3, 12.6.2). —end note ]

Cuestiones relacionadas