Quelle est la différence entre instancier un object en utilisant new vs sans

En C ++,

Outre l’allocation dynamic de la mémoire, existe-t-il une différence fonctionnelle entre les deux lignes de code suivantes:

Time t (12, 0, 0); //t is a Time object Time* t = new Time(12, 0, 0);//t is a pointer to a dynamically allocated Time object 

Je suppose bien sûr qu’un temps (int, int, int) ctor a été défini. Je me rends également compte que dans le second cas, il faudra le supprimer car il a été alloué sur le tas. Y a-t-il une autre différence?

La ligne:

 Time t (12, 0, 0); 

… alloue une variable de type Time dans la scope locale, généralement sur la stack, qui sera détruite à la fin de son étendue.

Par contre:

 Time* t = new Time(12, 0, 0); 

… alloue un bloc de mémoire en appelant soit ::operator new() soit Time::operator new() , puis appelle Time::Time() avec this ensemble à une adresse dans ce bloc de mémoire (et est également renvoyé comme le résultat de new ), qui est ensuite stocké dans t . Comme vous le savez, cela se fait généralement sur le tas (par défaut) et nécessite que vous le delete plus tard dans le programme, tandis que le pointeur dans t est généralement stocké dans la stack.

Une autre différence évidente réside dans l’access aux variables et aux méthodes de t.

 Time t (12, 0, 0); t.GetTime(); Time* t = new Time(12, 0, 0); t->GetTime(); 

En ce qui concerne le constructeur, les deux formes sont fonctionnellement identiques: elles ne feront qu’appeler le constructeur sur une instance d’object nouvellement allouée. Vous semblez déjà bien comprendre les différences en termes de modes d’allocation et de durée de vie des objects.

Je pense que vous comprenez déjà toutes les différences. En supposant que vous connaissiez bien la différence de syntaxe lors de l’access à un membre de t via un pointeur et une variable (enfin, le pointeur est aussi une variable mais je suppose que vous comprenez ce que je veux dire). Et en supposant également que vous connaissez la différence d’appel par valeur et appelez par référence lorsque vous passez à une fonction. Et je pense que vous comprenez également ce qui se passera si vous affectez t à une autre variable et effectuez des changements via cette autre variable. Le résultat sera différent selon que t est un pointeur ou non.

Il n’y a pas de différence fonctionnelle avec l’object entre l’allocation sur la stack et l’allocation sur le tas. Les deux invoqueront le constructeur de l’object.

Incidemment, je vous recommande d’utiliser boost_ptr ou scoped_ptr qui est aussi fonctionnellement équivalent lors de l’allocation sur le tas (avec l’utilité supplémentaire de scoped_ptr vous contraignant à copier des pointeurs non copiables):

 scoped_ptr 

Non .. Il n’y a pas d’autre différence.

Il n’y a pas d’autre différence à ce que vous savez déjà.

En supposant que votre code utilise le service de l’opérateur par défaut new.

  • Utilisez new : Appelez la nouvelle fonction opérateur pour obtenir de la mémoire dynamic, puis appelez la fonction constuctor.
  • Ne pas utiliser new: N’appelera pas la nouvelle fonction opérateur, juste pour appeler directement la fonction constuctor. La stack sera utilisée directement, pas besoin de malloc.
 void foo (Time t) { t = Time(12, 0, 0); } void bar (Time* t) { t = new Time(12, 0, 0); } int main(int argc, char *argv[]) { Time t; foo(t);//t is not (12,0,0),its value depends on your defined type Time's default constructor. bar(&t);//t is (12,0,0) return 0; }