Pregunta

Anteriormente pregunté por qué esto se considera malo:

class Example
{
 public: 
  Example(void);
  ~Example(void);
  void f() {}
}

int main(void)
{
 Example ex(); // <<<<<< what is it called to call it like this?

 return(0);
}

Ahora, entiendo que está creando un prototipo de función en su lugar que devuelve un tipo Ejemplo. Sin embargo, todavía no entiendo por qué funcionaría en g ++ y MS VC ++.

Mi siguiente pregunta es usar lo anterior, ¿sería válida esta llamada?

int main(void)
{
 Example *e = new Example();

 return(0);
}

? ¿Cuál es la diferencia entre eso y simplemente llamar al Ejemplo e () ??? Como sé que es un prototipo de función, pero parece que algunos compiladores lo perdonan y le permiten llamar al constructor predeterminado. También probé esto:

class Example
{
 private:
  Example();

 public:
  ~Example();
};

int main(void)
{
 Example e1(); // this works
 Example *e1 = new Example(); // this doesn't

 return(0);
}

Así que estoy un poco confundido :( Lo siento si esto se ha preguntado un millón de veces.

¿Fue útil?

Solución

esta pregunta será útil para comprender este comportamiento

Otros consejos

Es fácil, Daniel:

Example *e = new Example();

Eso no se parece a una función llamada "Ejemplo", ¿verdad? Una función tiene un valor de retorno, un nombre y parámetros. ¿Cómo encajaría eso arriba?

  

Ejemplo e1 (); // esto funciona

Sí, porque no crea ninguna instancia de Example en ningún lado. Simplemente le dice al código que hay una función definida en el espacio de nombres circundante en algún lugar, y posiblemente desee llamar a esa función. Sí, es cierto que para devolver un objeto de Ejemplo, se haría una instancia. Pero eso no significa que se haga una instancia en ese punto. Más bien, se crea una instancia en la función, cuando la llamas.

Hmm ... OK esto:

Ejemplo e1 ();

No funciona. Puede pensar que sí, o algún compilador lo está aceptando, pero no crea una instancia de Ejemplo llamada e1, solo declara un prototipo de función. Retire los soportes y haga lo que quiera.

Esto:

Ejemplo * e1 = nuevo Ejemplo ();

No funcionará porque el constructor es privado. Si hace público el constructor, creará el objeto en el montón y e1 será un puntero a ese objeto. Deberá eliminar el objeto cuando haya terminado con él.

Para la primera pregunta de ¿sería el " nuevo Ejemplo () " Sé valido. Sí, este es un código C ++ perfectamente legal. Aunque para ser completamente correcto, deberá eliminar el objeto antes de regresar de main (), de lo contrario, se producirá una pérdida de memoria.

Ejemplo:

int main(void)
{
 Example *e = new Example();
 delete e;
 return(0);
}

Para la última pregunta. La línea "Ejemplo e1 ();" es válido porque declara un prototipo de función. En realidad, esto no da como resultado que se ejecute el código de la máquina (bueno, tal vez espacio de pila). Simplemente dice, hay un prototipo de función sin argumentos, que devuelve un tipo de Ejemplo.

Sin embargo, la segunda línea fallará definitivamente. En este punto, está intentando ejecutar realmente el constructor para Ejemplo. Esto no es legal ya que la accesibilidad de la función es privada, de ahí el error del compilador.

Creo que debería diferenciar entre 'este análisis', 'esto compila', 'este enlace' y 'esto funciona', e intente pensar como un analizador / compilador / enlazador C ++ para ver que el primer ejemplo

Example e1(); // function prototype

parece una declaración de función. El analizador lo entenderá de este modo, por lo que no puede llamar, p. una función miembro en e1 . El compilador generará un símbolo que se refiere a alguna función (aún no se ve), pero como la función no se usa en ninguna parte, no se quejará. Si agrega este código, lo hará:

e1.f();// since e1 is a function, it has no member 'f' => compiler error

(como nota al margen: este código también compilará:

int a_function_prototype(int); // another prototype.
e1(); // should work!
a_function_prototype(5);

pero una vez que el compilador ha finalizado, el vinculador comenzará a buscar los cuerpos de funciones reales y no encontrará ninguno.

Ahora desde la línea

Example* e = new Example();

contiene una palabra clave new que el compilador reconoce, y sabe que solo se puede encontrar en la asignación + construcción de un nuevo objeto, generará código para hacerlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top