Quelle est la différence entre les lignes 1, 2, 3 et 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 ne le fait pas?
#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;
}
/* 1 */ Foo* foo1 = new Foo ();
Crée un objet de type Foo
dans la mémoire dynamique. foo1
pointe vers elle. Normalement, vous n'utiliseriez pas de pointeurs bruts en C++, mais plutôt un pointeur intelligent. Si Foo
était un type POD, cela initialiserait la valeur (cela ne s'applique pas ici).
/* 2 */ Foo* foo2 = new Foo;
Identique à auparavant, car Foo
n'est pas un type de POD.
/* 3 */ Foo foo3;
Crée un objet Foo
appelé foo3
en stockage automatique.
/* 4 */ Foo foo4 = Foo::Foo();
Utilise l'initialisation de copie pour créer un objet Foo
appelé foo4
en stockage automatique.
/* 5 */ Bar* bar1 = new Bar ( *new Foo() );
Utilise le constructeur de conversion de Bar
pour créer un objet de type Bar
dans la mémoire de stockage dynamique. bar1
est un pointeur sur celui-ci.
/* 6 */ Bar* bar2 = new Bar ( *new Foo );
Pareil qu'avant.
/* 7 */ Bar* bar3 = new Bar ( Foo foo5 );
Ceci est juste la syntaxe invalide. Vous ne pouvez pas déclarer une variable ici.
/* 8 */ Bar* bar3 = new Bar ( Foo::Foo() );
Travaillerait et fonctionnerait selon le même principe à 5 et 6 si bar3
n'était pas déclaré dans 7.
5 & 6 contenir des fuites de mémoire.
Une syntaxe comme new Bar ( Foo::Foo() );
n'est pas habituelle. C'est généralement new Bar ( (Foo()) );
- extra parenthèses compte pour l'analyse la plus frustrante. (corrigée)
foo4
est initialisé en construisant, copiant et détruisant par défaut un objet temporaire; généralement, ceci est élidé donnant le même résultat que 3.Foo foo5
est une déclaration et non une expression. Les arguments de fonction (et 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
dynamique à partir d'un Foo
temporaire.Les lignes 1,2,3,4 appellent le constructeur par défaut. Ils sont fondamentalement différents en ce que 1,2 est un objet créé dynamiquement et 3,4, de manière statique.
Dans la ligne 7, vous créez un objet dans l'appel d'argument. Donc c'est une erreur.
Et les lignes 5 et 6 sont une invitation à la fuite de mémoire.