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)
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. Foo foo5
est une déclaration, pas une expression; Les arguments de fonction (et de constructeur) doivent être des expressions. Foo()
plutôt que l’équivalent Foo::Foo()
(ou bien Foo::Foo::Foo::Foo::Foo()
) Quand est-ce que je les utilise?
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.