web-dev-qa-db-fra.com

Créer un objet: avec ou sans `new`

Duplicate possible:
Quelle est la différence entre instancier un objet avec new vs without

Ceci est probablement une question fondamentale, et aurait peut-être déjà été posée (par exemple, ici ); pourtant je ne le comprends toujours pas. Alors, laissez-moi vous le demander.

Considérez la classe C++ suivante:

class Obj{
    char* str;
public:
    Obj(char* s){
        str = s;
        cout << str;
    }
    ~Obj(){
        cout << "Done!\n";
        delete str;        // See the comment of "Loki Astari" below on why this line of code is bad practice
    }
};

quelle est la différence entre les extraits de code suivants:

Obj o1 ("Hi\n");

et

Obj* o2 = new Obj("Hi\n");

Pourquoi le premier appelle-t-il le destructeur, mais pas le second (sans appel explicite à delete)?

Lequel est préféré?

118
M.S. Dousti

Les deux font des choses différentes.

Le premier crée un objet avec durée de stockage automatique . Il est créé, utilisé, puis sort de la portée lorsque le bloc actuel ({ ... }) se termine. C'est le moyen le plus simple de créer un objet, et il en va de même lorsque vous écrivez int x = 0;

La seconde crée un objet avec durée de stockage dynamique et permet deux choses:

  • Un contrôle précis sur la durée de vie de l'objet, puisqu'il ne sort pas automatiquement du champ d'application; vous devez le détruire explicitement à l'aide du mot clé delete;

  • Création de tableaux avec une taille connue uniquement au moment de l'exécution, car la création de l'objet a lieu au moment de l'exécution. (Je n'entrerai pas dans les détails de l'allocation de tableaux dynamiques ici.)

Ni est préféré; cela dépend de ce que vous faites comme ce qui est le plus approprié.

Utilisez le premier sauf si vous avez besoin d'utiliser le dernier.

Votre livre C++ devrait couvrir cela assez bien. Si vous n'en avez pas, n'allez pas plus loin jusqu'à ce que vous ayez acheté et lu plusieurs fois ne de celles-ci .

Bonne chance.


Votre code d'origine est cassé, car il deletes un tableau char qu'il n'a pas new. En fait, rien newd la chaîne de style C; cela venait d'un littéral de chaîne. deleteing est une erreur (bien que celle-ci ne génère pas d'erreur de compilation, mais un comportement imprévisible au moment de l'exécution).

Habituellement, un objet ne devrait pas avoir la responsabilité de deletecharger quoi que ce ne soit pas lui-même new. Ce comportement devrait être bien documenté. Dans ce cas, la règle est complètement enfreinte.

136

Le premier alloue un objet avec une durée de stockage automatique, ce qui signifie qu'il sera automatiquement détruit à la sortie de la portée dans laquelle il est défini.

La seconde a alloué un objet avec une durée de stockage dynamique, ce qui signifie qu'il ne sera pas détruit avant que vous n'utilisiez explicitement delete pour le faire.

19
Jerry Coffin