Créer une instance de classe

Quelle est la différence entre les lignes 1, 2, 3, 4?

Quand est-ce que je les utilise?

Pourquoi la ligne 3 imprime le constructor Foo et la ligne 7 renvoie une erreur et la ligne 8 pas?

 #include  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; } 

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

Crée un object de type Foo en mémoire dynamic. foo1 pointe. Normalement, vous n’utiliseriez pas de pointeurs bruts en C ++, mais plutôt un pointeur intelligent. Si Foo était un type POD, cela effectuerait une initialisation de valeur (elle ne s’applique pas ici).

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

Identique à avant, car Foo n’est pas un type POD.

  /* 3 */ Foo foo3; 

Crée un object Foo appelé foo3 dans le stockage automatique.

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

Utilise l’initialisation de la copie pour créer un object Foo appelé foo4 dans le stockage automatique.

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

Utilise le constructeur de conversion de Bar pour créer un object de type Bar dans le stockage dynamic. bar1 est un pointeur vers elle.

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

Pareil qu’avant.

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

Ceci est juste une syntaxe invalide. Vous ne pouvez pas déclarer une variable à cet endroit.

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

Travaillerait et travaillerait selon le même principe à 5 et 6 si bar3 n’était pas déclaré le 7.

5 et 6 contiennent des memory leaks.

Syntaxe comme new Bar ( Foo::Foo() ); n’est pas habituel. C’est généralement new Bar ( (Foo()) ); parenthèse supplémentaire compte pour l’parsing la plus vexante. (corrigée)

  1. Alloue de la mémoire dynamic à partir du magasin gratuit et crée un object dans cette mémoire en utilisant son constructeur par défaut. Vous ne le supprimez jamais, de sorte que la mémoire est perdue.
  2. Fait exactement la même chose que 1; Dans le cas de types définis par l’utilisateur, les parenthèses sont facultatives.
  3. Alloue de la mémoire automatique et crée un object dans cette mémoire en utilisant son constructeur par défaut. La mémoire est libérée automatiquement lorsque l’object est hors de scope.
  4. Similaire à 3. En théorie, l’object nommé foo4 est initialisé par défaut, en copiant et en détruisant un object temporaire; En général, cela donne le même résultat que 3.
  5. Alloue un object dynamic, puis initialise une seconde en copiant le premier. Les deux objects ont fui; et il n’y a aucun moyen de supprimer le premier puisque vous ne le gardez pas.
  6. Fait exactement la même chose que 5.
  7. Ne comstack pas Foo foo5 est une déclaration, pas une expression; Les arguments de fonction (et de constructeur) doivent être des expressions.
  8. Crée un object temporaire et initialise un object dynamic en le copiant. Seul l’object dynamic est divulgué; le temporaire est détruit automatiquement à la fin de l’expression complète. Notez que vous pouvez créer le temporaire avec juste Foo() plutôt que l’équivalent Foo::Foo() (ou bien Foo::Foo::Foo::Foo::Foo() )

Quand est-ce que je les utilise?

  1. Ne le faites pas, sauf si vous aimez les décorations inutiles sur votre code.
  2. Lorsque vous souhaitez créer un object qui dépasse la scope actuelle. N’oubliez pas de le supprimer lorsque vous en avez terminé et d’apprendre à utiliser des pointeurs intelligents pour contrôler plus facilement la durée de vie.
  3. Lorsque vous voulez un object qui n’existe que dans l’étendue actuelle.
  4. Ne le faites pas, à moins que vous ne pensiez que 3 soit ennuyeux et que vous devez append une décoration inutile.
  5. Ne le faites pas, car il y a une fuite de mémoire sans aucune chance de récupération.
  6. Ne le faites pas, car il y a une fuite de mémoire sans aucune chance de récupération.
  7. Non, car il ne comstackra pas
  8. Lorsque vous souhaitez créer une Bar dynamic à partir d’un Foo temporaire.

Les lignes 1,2,3,4 appellent le constructeur par défaut. Ils sont essentiellement différents car 1,2 sont des objects créés dynamicment et 3,4 sont des objects créés de manière statique.

Dans la ligne 7, vous créez un object dans l’appel d’argument. Donc c’est une erreur.

Et les lignes 5 et 6 invitent à la fuite de mémoire.