Pregunta Creando una instancia de clase


¿Cuál es la diferencia entre las líneas 1, 2, 3, 4?

¿Cuándo uso cada uno?

Por qué la línea 3 imprime el constructor Foo y la línea 7 devuelve un error y la línea 8 no?

#include <iostream>     
using namespace std;

class Foo
 {
   public:
   Foo ( )
   {
      cout << "constructor Foo\n";
   }               
};

class Bar
 {
   public:
   Bar ( Foo )
   {
      cout << "constructor Bar\n";
   }
};

int main()
{
   /* 1 */ Foo* foo1 = new Foo ();
   /* 2 */ Foo* foo2 = new Foo;
   /* 3 */ Foo foo3;
   /* 4 */ Foo foo4 = Foo::Foo();

   /* 5 */ Bar* bar1 = new Bar ( *new Foo() );
   /* 6 */ Bar* bar2 = new Bar ( *new Foo );
   /* 7 */ Bar* bar3 = new Bar ( Foo foo5 );
   /* 8 */ Bar* bar3 = new Bar ( Foo::Foo() );

   return 1;
}

74
2017-09-03 13:18


origen


Respuestas:


   /* 1 */ Foo* foo1 = new Foo ();

Crea un objeto de tipo Foo en memoria dinámica. foo1 apunta a eso. Normalmente, no usaría punteros crudos en C ++, sino un puntero inteligente. Si Foo era un tipo de POD, esto llevaría a cabo una inicialización de valor (no se aplica aquí).

   /* 2 */ Foo* foo2 = new Foo;

Idéntico a antes, porque Foo no es un tipo de POD.

   /* 3 */ Foo foo3;

Crea un Foo objeto llamado foo3 en almacenamiento automático.

   /* 4 */ Foo foo4 = Foo::Foo();

Utiliza la inicialización de copia para crear un Foo objeto llamado foo4 en almacenamiento automático.

   /* 5 */ Bar* bar1 = new Bar ( *new Foo() );

Usos Barconstructor de conversiones para crear un objeto de tipo Bar en almacenamiento dinámico bar1 es un puntero a eso.

   /* 6 */ Bar* bar2 = new Bar ( *new Foo );

Igual que antes.

   /* 7 */ Bar* bar3 = new Bar ( Foo foo5 );

Esta es solo una sintaxis inválida. No puedes declarar una variable allí.

   /* 8 */ Bar* bar3 = new Bar ( Foo::Foo() );

Funcionaría y trabajaría por el mismo principio a 5 y 6 si bar3 no fue declarado en 7.

5 y 6 contener fugas de memoria.

Sintaxis como new Bar ( Foo::Foo() ); no es usual Es por lo general new Bar ( (Foo()) ); - cuenta de paréntesis extra para el análisis más irritante. (corregido)


89
2017-09-03 13:24



  1. Asigna una memoria dinámica de la tienda gratuita y crea un objeto en esa memoria utilizando su constructor predeterminado. Nunca lo borras, entonces la memoria se pierde.
  2. Hace exactamente lo mismo que 1; en el caso de los tipos definidos por el usuario, los paréntesis son opcionales.
  3. Asigna una memoria automática y crea un objeto en esa memoria usando su constructor predeterminado. La memoria se libera automáticamente cuando el objeto se sale del alcance.
  4. Similar a 3. En teoría, el objeto nombrado foo4 se inicializa por defecto: construir, copiar y destruir un objeto temporal; generalmente, esto se elimina dando el mismo resultado que 3.
  5. Asigna un objeto dinámico, luego inicializa un segundo copiando el primero. Ambos objetos se filtraron; y no hay forma de eliminar el primero ya que no lo mantiene puntero.
  6. Hace exactamente lo mismo que 5.
  7. No compila Foo foo5 es una declaración, no una expresión; los argumentos de función (y constructor) deben ser expresiones.
  8. Crea un objeto temporal e inicializa un objeto dinámico copiándolo. Solo se filtra el objeto dinámico; el temporal se destruye automáticamente al final de la expresión completa. Tenga en cuenta que puede crear el temporal con solo Foo() en lugar de su equivalente Foo::Foo() (o de hecho Foo::Foo::Foo::Foo::Foo())

¿Cuándo uso cada uno?

  1. No, a menos que quieras decoraciones innecesarias en tu código.
  2. Cuando desee crear un objeto que sobreviva al alcance actual. Recuerda eliminarlo cuando hayas terminado con él y aprender a usarlo punteros inteligentes para controlar la vida más conveniente.
  3. Cuando quiere un objeto que solo existe en el alcance actual.
  4. No, a menos que piense que 3 parece aburrido y qué agregar una decoración innecesaria.
  5. No, porque pierde la memoria sin posibilidad de recuperación.
  6. No, porque pierde la memoria sin posibilidad de recuperación.
  7. No, porque no compilará
  8. Cuando quieres crear una dinámica Bar de un temporal Foo.

17
2017-09-03 14:19



Las líneas 1,2,3,4 llamarán al constructor predeterminado. Son diferentes en esencia ya que 1,2 es un objeto creado dinámicamente y 3,4 son objetos creados estáticamente.

En la línea 7, creas un objeto dentro de la llamada de argumento. Entonces es un error.

Y las líneas 5 y 6 son una invitación a la pérdida de memoria.


4
2017-09-03 13:25