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

Langage C++ Discussion :

Différence d'instanciation d'objets


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2011
    Messages : 5
    Par défaut Différence d'instanciation d'objets
    Bonjour,

    J'ai beau chercher sur Google je ne trouve pas de site qui explique précisément la différence entre un object instancié de la sorte:

    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyObject *myobject = new MyObject(10);
    La portée, la mémoire, tout y est expliqué mais aucun exemple concret qui me montre où un object instancié avec la méthode 1 ne fonctionnerait pas alors qu'un objet instancié avec la méthode 2 irait...

    QUelqu'un aurait un petit bout de code explicatif ?

    Merci

    a+

  2. #2
    Membre expérimenté
    Homme Profil pro
    Analyse système
    Inscrit en
    Novembre 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyse système
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 227
    Par défaut
    Je pense que tu as déjà compris que l'un des deux objets est statique, et l'autre est dynamique.
    La seul différence est donc la facon dont tu gères la mémoire.
    Dans le cas de l'objet statique tu alloues la mémoire tout de suite et ce jusqu'à la fin de la portée de l'objet.
    Dans le cas de l'objet dynamique tu alloues la mémoire quand tu en as besoin, et tu la libère quand tu n'en as plus besoin; celà donne donc plus de souplesse mais demande également plus de rigueur.

    A près dans d'autre cas de figure, principalement celui de l'héritage il est intéressant d'utiliser des objets dynamiques. Imagine que tu ais les classes B,C,D qui hérite de A. Si tu veux toutes les mémoriser dans un tableau la seule solution consiste à créer un tableau (ou un conteneur) de pointeur sur A et tu alloueras dynamiquent les objets B,C,D pour pouvoir les ranger dans le tableau ce que tu ne pourras pas faire avec des objets statiques.
    Voici donc un exemple parmi d'autre de l'avantage de l'objet dynamique.

    Un des autres avantages et le passage par pointeur d'un objet dans une fonction qui evite de recopier tout l'objet en mémoire (donc gain de temps et d'espace mémoire), même si en C++ tu peux avoir la même chose avec un objet statique passé par référence.

    Autre chose : la portée d'un objet statique et fixé, celle d'un objet dynamique non, tout le temps que tu ne l'a pas désalloué, il existe (c'est souvent une des raisons des fuites mémoires)

  3. #3
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    618
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 618
    Par défaut
    Salut,

    Exemple concret:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    MaClass* creerMaClass1()
    {
      MaClass* maClass = new MaClass();
      return maClass;
    }
     
    MaClass* creerMaClass2()
    {
      MaClass maClass();
      return &maClass;
    }
     
    int main()
    {
      MaClass* maClass1 = creeMaClass1();
      MaClass* maClass2 = creeMaClass2();
      // maintenant si tu essaye d'utiliser maClass2 tu te prendra un joli segFault dans les dents :)
     
    }
    Dans l'absolu, on pourrait tout coder en allocation dynamique, mais il faudrait tout libérer à la main tout le temps... J'imagine même pas les lignes de delete en fin de fonction et le nombre de fuite...

  4. #4
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par AF_2.8 Voir le message
    (...)
    Dans le cas de l'objet statique tu alloues la mémoire tout de suite et ce jusqu'à la fin de la portée de l'objet.
    (...)
    Sur le fond, c'est juste, mais sur la forme, c'est extrêmement ambigüe par rapport aux notions C++.

    Idéalement il faudrait éviter d'utiliser le terme statique ici car il porte à confusion avec le mot clé static.

    Et la notion de "fin de la portée de l'objet" n'est pas très claire non plus. (En programmation, la portée signifie: d'où est-ce que je peux utiliser quelque-chose)
    Il faudrait mieux dire "fin du bloc du code où est déclaré l'objet" (sauf pour le cas des variables static qui ne sont désinstanciées qu'à la fin du programme).

  5. #5
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    @AF_2.8:
    Imagine que tu ais les classes B,C,D qui hérite de A. Si tu veux toutes les mémoriser dans un tableau la seule solution consiste à créer un tableau (ou un conteneur) de pointeur sur A et tu alloueras dynamiquent les objets B,C,D pour pouvoir les ranger dans le tableau ce que tu ne pourras pas faire avec des objets statiques.
    Pour le début oui, mais pas besoin d'allouer dynamiquement (je ne crois pas qu'on parle d'allocation statique, on dirait plutôt sur la pile, et "objets statiques" désigne autre chose).

    @OP: Imagines que tu ais un programme qui demance à l'utilisateurs (via un flux d'entrée, console, fichier, autre), combien d'objets de tel entité il doit créer par exemple, comment tu ferais sans utiliser l'allocation dynamique ? (directement ou indirectement (*) ). Les cas où l'utilisation de l'allocation dynamique est indispensable c'est lorsque que tu ne peux pas prévoir à l'avance ce que tu auras besoin de créer.

    (*) Si tu passes par un tableau dynamique du genre vector, elle est caché mais reste présente.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2011
    Messages : 5
    Par défaut
    Merci pour toutes vos réponses!

    Je pense avoir mieux compris. En gros on est pas souvent "obligé" de passer par du dynamique. La façon "statique" est correcte aussi mais dans certain cas je serai contraint de coder avec du dynamique. Je peux donc continuer comme j'avais commencé, merci beaucoup

    Merci pour les réponses rapides et à bientôt,

  7. #7
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Il y a une manière de voir simple qui peut t'aider à rapidement choisir ta manière d'instancier ton objet.

    L'idée fondamentale est que ce soit deux manières de donner un temps de vie à ton objet. Les notions de zone de stockage (pile ou tas) sont des détails d'implémentation.

    Si tu veux que ton objet vive uniquement le temps d'execution du bloc en cours :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    {
      ///
      MonType mon_object; 
     
    } /// mon_objet est implicitement détruit ici
    Par contre si tu veux déterminer "à la main" le moment où ton objet doit être détruit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    {
     
      MonType* mon_object = new MonType(); 
     
    } /// mon_objet est implicitement n'est pas détruit ici
     
     
    //// blah blah blah du code
     
    void finish_him( MonType* mon_objet )
    {
        delete mon_objet; // mon objet (si valide) sera détruit ici 
    }
    Dans ce cas n'oublie jamais de faire en sorte que chaque appel à new à l'execution ait son appel à delete quelque part. Cela suggère que tu ais toujours un pointeur valide vers ton objet à tout moment. Sinon, tu as un "memory leak", une fuite de mémoire (fuite parcequ'elle est là, qu'elle n'est jamais désallouée mais tu n'y as plus accès et donc tu ne peux pas la libérer).

    Une fois que tu as compris ça, tu comprends aussi qu'il se peut que tu veuilles définir une règles "générale" qui va régir la vie de certains de tes objets.
    En C++, on appelle ça des "smart pointer" (pointeur intelligents).

    Chaque type de smart pointer va avior une règle de gestion différente. C'est un tout autre sujet alors je te conseil de jetter un oeil à ce que fournis boost pour comprendre.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2011
    Messages : 5
    Par défaut
    Merci pour toute ces réponses...

    Et en fait en codant ce matin j'ai vite compris l'utilité de la portée, j'ai été obligé de créer des objets dynamiques pour mes besoins, suivants vos conseils, super!

    Par contre libérer la mémoire avec le delete, je ne le fais que quand je n'ai plus besoin de ces objets. Ma question est la suivante: j'ai plusieurs objets, qui vont me servir tout au long de mon programme, en gros j'en aurai besoin jusqu'à la dernière instruction de mon programme. Dois-je quand même les deleter? Ou cela va se faire tout seul au moment ou mon programme va se terminer non?

    Merci,

    a+

  9. #9
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    1. delete n'est jamais appelé tout seul (sauf avec des smart pointer)
    2. La plupart des OS d'aujourd'hui vont de toutes façons libérer la mémoire de l'application d'un coup. Donc tu ne verras pas le problème.
    3. Par contre si tu ne libères pas ta mémoire à la fin de l'application, c'est très "sale". Si un jour tu as besoin que ton application soit modifiée (et ça arrivera) il y aura forcément des problèmes (performance et mémoire) qui seront liés à cette fuite mémoire.


    Résumé : delete toujours tes objets alloués avec new.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2011
    Messages : 5
    Par défaut
    Donc en gros si je ne la libère pas elle reste prise par l'OS même quand mon programme a terminé de tourner? quelle idée bizarre Donc le seul moyen de la libérer est de redémarrer la machine?

    Ok donc à la fin de mon main je delete les vars maintenant

    Merci,

Discussions similaires

  1. [Reflection] Instancier un objet
    Par bl@st dans le forum API standards et tierces
    Réponses: 4
    Dernier message: 28/10/2008, 11h09
  2. [POO] Instancier un objet avec le nom de la classe
    Par shinchun dans le forum Langage
    Réponses: 4
    Dernier message: 08/06/2006, 13h44
  3. Réponses: 6
    Dernier message: 18/01/2006, 16h26
  4. instancier un objet Excel
    Par RobinNono dans le forum ASP
    Réponses: 1
    Dernier message: 13/12/2005, 15h51
  5. Différence, exemple procédural, événementiel, objet ?
    Par ludophil dans le forum Débuter
    Réponses: 3
    Dernier message: 26/10/2005, 08h35

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