IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Différence opérateur new et constructeur


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 61
    Points : 47
    Points
    47
    Par défaut Différence opérateur new et constructeur
    Bonjour,

    Je voudrais savoir à quoi sert l'opérateur new en C++.
    J'ai compris qu'il servait à allouer de la mémoire, mais je ne vois pas la
    différence entre utiliser l'opérateur new et appeler directement le constructeur :
    Classe maClasse = new Classe();
    et
    Classe maClasse();

    Merci

  2. #2
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Points : 444
    Points
    444
    Par défaut
    La syntaxe correcte est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Classe* maClasse = new Classe();
    Ici la mémoire est allouée dynamiquement (i.e. dans le tas) et c'est à toi de t'occuper de sa libération lorsque tu n'en as plus besoin (via un appel à delete sur le pointeur alloué).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Classe maClasse;
    //ou
    Classe maClasse(parametre);
    Ici la mémoire est allouée automatiquement (i.e. sur la pile) et libérée (automatiquement) dès que tu sors de la portée de cette allocation.

  3. #3
    Membre expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Points : 3 344
    Points
    3 344
    Par défaut
    Bonjour,

    Tu ne peux pas faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Classe maClasse = new Classe();
    Ca doit te retourner une erreur...

    L'opérateur new ne doit être utilisé que pour allouer dynamiquement de la mémoire.

    Pour créer un objet, tu peux utiliser la syntaxe suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    {
        Classe maClasse;
        Classe maClasse2 = Classe();
    }
    Ces deux lignes sont strictement équivalentes. Elles définissent un objet de type Classe en appelant le constructeur par défaut de Classe. La deuxième met juste un peu plus en évidence l'appel au constructeur.
    Dans ces deux cas, la portée de l'objet est liée à la portée de la variable qui le référence. Dans l'exemple que je donne, la portée est limitée aux accolades. Donc, après la fermeture des accolades, l'objet est détruit et la mémoire est libérée. Il ne peut plus être utilisé.

    Les pointeurs te permettent d'allouer dynamiquement de la mémoire. Par exemple, si tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    {
        Classe * maClasse = new Classe();
    }
    Tu crées un objet de type Classe, et tu stocke son adresse dans le pointeur maClasse. Cette fois, la portée de l'objet n'est plus limitée par la variable qui le référence. Après fermeture des accolades, maClasse n'existe plus (le pointeur), mais l'objet existe toujours, et peut être encore utilisé (si on a son adresse). Et il faut penser à libérer la mémoire une fois qu'on en a plus besoin avec delete.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 61
    Points : 47
    Points
    47
    Par défaut
    Merci beaucoup. Désolé pour le * que j'avais oublié. J'ai compris la différence entre les deux.

  5. #5
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Citation Envoyé par Eusebe
    Pour créer un objet, tu peux utiliser la syntaxe suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    {
        Classe maClasse;
        Classe maClasse2 = Classe();
    }
    Ces deux lignes sont strictement équivalentes. Elles définissent un objet de type Classe en appelant le constructeur par défaut de Classe. La deuxième met juste un peu plus en évidence l'appel au constructeur.
    Pas vraiment non.
    La seconde fait un appel au constructeur par défaut pour générer un temporaire, puis un appel au constructeur de recopie, et enfin détruit le temporaire généré.

    A supposer que le compilateur sache optimiser et virer le temporaire inutile, la présence d'un constructeur de recopie public et non explicite reste nécessaire.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    En fait, le constructeur ne fait qu'une chose: initialiser ton objet en fonction des informations qui lui sont fournies (en considérant que le constructeur par défaut travaille avec "aucune information fournie")...

    new, quant à lui travaille uniquement sur des pointeurs (Classe *MaClasse), et va en fait effectuer trois actions distinctes:

    • Allouer en mémoire un espace équivalent à sizeof(objet à créer)
    • définir l'emplacement en mémoire où se trouvent les différents membre de ton objet
    • appeler le constructeur qui suit de manière à initialiser les différents membres

    Normalement, si l'une de ces trois actions échoue, new renvoie une exception de type bad_alloc()...

    En conclusion, on peut dire que new est le pendant d'un malloc en C...(à ceci pres que, comme je l'ai signalé plus tot, il effectue certaines actions supplémentaires par rapport au malloc )

    Il est donc à utiliser, finalement, exactement dans les memes circonstances que le malloc du C, à savoir l'allocation dynamique de la mémoire pour un objet, et, comme le malloc du C, il faut penser à libérer soi meme la mémoire allouée grace à delete (ou delete[] dans le cas de l'allocation d'un tableau d'objets) qui, lui, travaillera dans le sens inverse, en
    • appelant le destructeur
    • libérant la mémoire allouée dynamiquement
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Points : 3 344
    Points
    3 344
    Par défaut
    Citation Envoyé par Luc Hermitte
    La seconde fait un appel au constructeur par défaut pour générer un temporaire, puis un appel au constructeur de recopie, et enfin détruit le temporaire généré.

    A supposer que le compilateur sache optimiser et virer le temporaire inutile, la présence d'un constructeur de recopie public et non explicite reste nécessaire.
    Ah ?
    J'étais pourtant persuadé que ça le faisait bien. Et en regardant le cours avec lequel j'ai commecé le C++, je comprend d'où vient ma confusion...
    L'appel d'un constructeur dans une expression comportant un signe = peut prêter à confusion, à cause de sa ressemblance avec une affectation. Or, en C++, l'initialisation et l'affectation sont deux opérations distinctes, du moins lorsqu'elles concernent des variables d'un type classe : l'initialisation consiste à donner une première valeur à une variable au moment où elle commence à exister ; l'affectation consiste à remplacer la valeur
    courante d'une variable par une autre valeur ; les opérations mises en oeuvre par le compilateur, constructeur dans un cas, opérateur d'affectation dans l'autre, ne sont pas les mêmes.
    C'est en page 15 du livre "Le langage C++" de Henri Garreta.
    Comme il ne parle pas de constructeur de recopie, mais juste de constructeur, je ne pensais pas qu'il était appelé..

    Au temps pour moi. Merci d'avoir corrigé !

  8. #8
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Eusebe
    Comme il ne parle pas de constructeur de recopie, mais juste de constructeur, je ne pensais pas qu'il était appelé.
    Il peut etre remplace par le constructeur direct, mais il doit etre accessible et explicite.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Surcharge de l'opérateur new
    Par :Bronsky: dans le forum C++
    Réponses: 17
    Dernier message: 27/10/2010, 21h33
  2. Redéfinition opérateurs new et delete globaux
    Par bolhrak dans le forum C++
    Réponses: 8
    Dernier message: 30/07/2007, 11h34
  3. l opérateur new
    Par deubelte dans le forum C++
    Réponses: 6
    Dernier message: 01/02/2007, 07h34
  4. opérateur new visual c++
    Par zerocoolyoussef dans le forum Visual C++
    Réponses: 4
    Dernier message: 20/11/2006, 20h01
  5. namespace et opérateur new
    Par Sylvain Rousseau dans le forum C++
    Réponses: 3
    Dernier message: 06/01/2005, 23h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo