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 :

L'operateur new, avec ou sans ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 24
    Par défaut L'operateur new, avec ou sans ?
    Bonjour,

    Ca fait un moment que je cherches sur le net et il y a un truc que je ne comprend pas. C'est peut-etre propre au compilo, m'enfin j'en sais rien (Borland c++ builder 6.0). Je pense que c'est lie au C++.

    Pourquoi a-t-on besoin du new en C++ ?

    En JAVA ou en C# si on utilise pas new on a un pointeur null.

    Mais en C++, ca m'etonne, mais on dirait qu'en declarant simplement la classe:

    MyClass classe1;

    On peut deja acceder aux proprietes et aux methodes de classe1. Alors d'accord les champs ne sont pas initialises. Mais vous ne trouvez pas ca etrange ?

    Qu'est ce qui se passe quand on lui dit MyClass classe1 ?

    Pourquoi par la suite si on fait classe1.myMethod() ca ne plante pas ?

    Je sais que d'ordinaire on fait :
    MyClass* classe1 = new MyClass();

    Mais a quoi ca rime si le constructeur ne fait rien ?

    Ecrire simplement "MyClass classe1;" demande moins d'effort et a l'air de faire la meme chose...

  2. #2
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Par défaut
    dans ton appel il y a un appel implicite au constructeur.

    Mais la principale difference réside dans le fait que quand tu fais une allocation par l'intermedaire d'un pointeur, c'est que tu controlle la memoire (donc la durée et le lieu de vie) de ton objet alloué.

    Sa vie pourra etre plus longue que le bloc dans lequelle il a été declaré ( tant qu'il a pas été deleté) (Il n'y a pas de Garbage collector dans le C++ non managé). Mais je laisse les docteur en la matière de donner plus d'informations.

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

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Tu as trois manières d'allouer de la mémoire en C++ : automatique (sur la pile), dynamique (sur le tas) et statique.

    Lorsque tu effectues un appel du type :
    tu alloues myClass sur la pile, le constructeur par défaut est appelé, et les membres de myClass sont initialisés à leur valeur par défaut. Un appel de la forme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MyClass myClass(param1, param2)
    a exactement le même effet (allocation sur la pile), sauf que là tu spécifies des paramètres d'initialisation.

    Dans le cas de l'allocation dynamique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MyClass* myClass = new MyClass;
    la mémoire est d'abord allouée puis le constructeur de l'objet est appelé, les membres sont initialisés, etc, bref comme dans le cas de l'allocation automatique.

    La grosse différence entre allocation automatique et allocation dynamique est la durée de vie :

    - dans le cas de l'allocation automatique ton objet est détruit à la fin de la portée courante (ou si c'est un membre d'une autre classe, il est détruit automatiquement lorsque le destructeur de cette classe est appelé).
    - dans le cas de l'allocation dynamique, il est détruit lorsque tu appelles l'operateur delete, la libération de la mémoire est donc à ta charge.

  4. #4
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 24
    Par défaut
    Edit : Je viens de lire le message ci-dessus, OK je vois. Finalement c'est meme tres pratique de ne pas utiliser new si on traite un objet local, comme ca on evite d'avoir a l'appeler avec delete.

    Merci


    Mais alors si on fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void function()
    {
    MyClass myOBject;
    }
    L'objet myObject reste en memoire apres function, et ne sera jamais desaloue.

    Donc pour desalouer on peut faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void function()
    {
    MyClass myOBject;
    delete &myOBject;
    }
    Donc si myObject est un objet local a function, ce serait pas mieux de faire comme ci-dessus plutot que:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void function()
    {
    MyClass* myOBject = new MyClass();
    delete myOBject;
    }
    En tous cas ca revient completement au meme on est d'accord ?

  5. #5
    Membre émérite
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Février 2004
    Messages
    644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Février 2004
    Messages : 644
    Par défaut
    L'allocation sur la pile, n'a pas besoin d'être désalloué car tu travailles avec une instance de classe qui sera directement détruit lorsque l'on programme sortira du scope où a été déclarée ton instance.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void foo( ) {
        /// Allocation de mémoire sur la pile pour une instance de MyClass
        MyClass myClass;
     
        /// arrivé à la fin du bloc ( donc on sort du scope dans lequel MyClass a été
        /// déclaré -> destruction automatique de l'instance
    }
    Maintenant si tu travailles avec un pointeur sur une instance d'une classe, tu devras toi-même gérer la mémoire, c'est à dire créer une instance de ta classe sur le TAS et la détruire.

    pour créer et détuire, new et delete.
    exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void bar( ) {
        MyClass * pMyClass;
        pMyClass = new MyClass;
     
        delete pMyClass;
    }
    Par contre écrire ceci, ne sert strictement à rien,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void foobar() {
        MyClass toto;
        delete &toto; /// Le compilateur acceptera mais je ne connais pas le résultat lors du runtime
    }

  6. #6
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 24
    Par défaut
    Merci pour la derniere precision.

    Je viens de retirer le resolu car un truc me chagrine. (Un test que je viens de faire)

    Si dans la classe MyClass, j'ai un tableau de 1 000 000 d'ints (c'est pas beaucoup quand meme, a peine 4Mo), j'obtiens un stack overflow.

    C'est grave docteur ?

    Comment ca se fait qu'il n'ait pas de probleme dans le cas ou je fais un new explicite (je vois bien que mes 4 Mo sont alloues en regardant l'etat de la memoire sous windows...)?

    Ca signifie qu'on peut declarer les objets comme ca:

    MyClass myObject;

    Mais que attention il ne faut pas qu'il soit trop gros ?

    Comment connaitre la limite ?

  7. #7
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 24
    Par défaut
    Ah ben je vais me repondre tout seul ce coup-ci.

    Si vous avez le meme probleme faites un tour ici :

    http://www.devx.com/tips/Tip/14276

    Ca correspond exactement a mon cas, l'objet local est trop gros pour la pile.

    Dans le cas d'un new, l'objet n'est plus vraiment local (meme si on perd le pointeur (a eviter quand on alloue plus de 1 Mo je pense...)), donc tout de suite ca va mieux.

    Ahlala j'vous jure...

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

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Citation Envoyé par swirtel Voir le message
    Par contre écrire ceci, ne sert strictement à rien,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void foobar() {
        MyClass toto;
        delete &toto; /// Le compilateur acceptera mais je ne connais pas le résultat lors du runtime
    }
    C'est même pire que "ne sert à rien", c'est dangereux. Le programme va essayer de libérer deux fois la mémoire, plantage assuré.

    Finalement c'est meme tres pratique de ne pas utiliser new si on traite un objet local, comme ca on evite d'avoir a l'appeler avec delete.
    Le point le plus important n'est pas vraiment le côté pratique, mais le fait que tu es assuré que ton objet sera détruit lorsque tu sors de la portée courante. C'est particulièrement intéressant dans le cas de méthodes pouvant lancer des exceptions pour assurer la libération des ressources allouées.

  9. #9
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Pareil si tu doit alloué dynamiquement une class.
    Tu as aussi std::auto_ptr. Qui gèrera le pointeur

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void foobar() 
    {
        std::auto_ptr<MyClass> toto (new MyClass);
     
    toto->blabla();
     
    .
    .
    .
     
    }//une fois sortie std::auto_ptr va detruire l'instance de MyClass

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

Discussions similaires

  1. Création délégué avec ou sans new
    Par zworg dans le forum VB.NET
    Réponses: 3
    Dernier message: 07/03/2012, 16h59
  2. avec ou sans new
    Par menthol34 dans le forum Langage
    Réponses: 2
    Dernier message: 16/05/2009, 14h34
  3. Allocation Dynamique de Memoire Avec Operateur New
    Par msstaf dans le forum C++Builder
    Réponses: 3
    Dernier message: 30/06/2006, 15h49
  4. Saut avec ou sans condition
    Par Frenchghost dans le forum Assembleur
    Réponses: 16
    Dernier message: 03/01/2005, 13h28
  5. [C#] [EXCEL] Travailler avec EXCEL sans ouvrir le logiciel
    Par Fabsou dans le forum Windows Forms
    Réponses: 3
    Dernier message: 16/07/2004, 10h29

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