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 :

relation de composition et destructeur


Sujet :

C++

  1. #1
    Membre habitué
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2008
    Messages : 289
    Points : 151
    Points
    151
    Par défaut relation de composition et destructeur
    Bonjour,
    je code un test unitaire à propos de la relation de composition entre deux classes.
    Mon code:
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    class Moteur {
        private:
            string type;
     
        public:
            Moteur(const string&);
    		~Moteur();
    };
     
    Moteur::Moteur(const string& t):type(t)
    {
    	cout << "Xtor Moteur de type " << type << endl;
    }
     
    Moteur::~Moteur()
    {
    	cout << "Dtor Moteur de type " << type << endl;
    }
     
    class Voiture {
        private:
            string marque;
            Moteur moteur;  //implante la  composition un objet dans l’objet
        public:
    		Voiture(const string& marque, const string& moteur);
    		~Voiture();
    };
     
    Voiture::Voiture(const string& ma, const string& mo):marque(ma), moteur(mo)
    {
    	cout << "Xtor Voiture de marque " << ma << endl;
    }
     
    Voiture::~Voiture()
    {
    	cout << "Dtor Voiture de marque " << marque << endl;
    }
     
    int main()
    {
    	string marque("Volvo");
    	string moteur("TX 617");
     
    	Voiture V(marque, moteur);
    	exit(EXIT_SUCCESS);
    }
    Je vois bien passer le constructeur du moteur puis celui de la voiture.
    Par contre je ne vois jamais les cout dans les destructeurs. Pourtant il n'y a pas d'ambigüité quand V sort de sa portée, on devrait les traverser ...
    Merci pour vos réponses.

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    On quitte prématurément le programme. Les destructeurs ne sont pas appelés. En supprimant cette ligne ou en faisant un return à la place, les destructeurs sont correctement appelés.

    Voir par exemple https://stackoverflow.com/questions/...n-calling-exit

  3. #3
    Membre habitué
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2008
    Messages : 289
    Points : 151
    Points
    151
    Par défaut
    Bonjour et merci pour la réponse.
    Effectivement ça fonctionne avec un return mais je ne comprend pas vraiment pourquoi.
    1- exit() c'est pour quitter un processus, celui créé par l'appel à la fonction main(). A ce niveau là, j'ai lu et on m'a toujours dit que c'était mieux écrit qu'avec un return qui est fait pour quitter une fonction. Bon d'accord, ça se mord un peu la queue.
    2- pourquoi est-ce que exit quitte plus prématurément que return ? au niveau du exit, à priori l'objet V est complètement construit. (à moins que exit n'appelle pas le destructeur des objets?

    Merci pour ta réponse.

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    effectivement c'est assez subtil, mais c'est écrit dans sa documentation : exit, cplusplus.com en anglais.

    Terminates the process normally, performing the regular cleanup for terminating programs.

    Normal program termination performs the following (in the same order):
    *) Objects associated with the current thread with thread storage duration are destroyed (C++11 only).
    *) Objects with static storage duration are destroyed (C++) and functions registered with atexit are called.
    *) All C streams (open with functions in <cstdio>) are closed (and flushed, if buffered), and all files created with tmpfile are removed.
    *) Control is returned to the host environment.

    Note that objects with automatic storage are not destroyed by calling exit (C++).

    If status is zero or EXIT_SUCCESS, a successful termination status is returned to the host environment.
    If status is EXIT_FAILURE, an unsuccessful termination status is returned to the host environment.
    Otherwise, the status returned depends on the system and library implementation.

    For a similar function that does not perform the cleanup described above, see quick_exit.
    "Objects associated with the current thread with thread storage duration are destroyed (C++11 only).": je pense qu'il faut le traduire par toutes les variables locales dans le main ne sont pas détruites ... qu'à partir du C++11/ C++ moderne.
    en C, cela ne doit pas poser de problème parce que lorsque le processus se termine, il n'y a pas d'appel automatique comme les destructeurs (et que le minimum de nettoyage est fait) ... mais pas en C++.

  5. #5
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    La ligne à lire c'est surtout :
    Note that objects with automatic storage are not destroyed by calling exit (C++).

    Ça indique qu'appeler exit() détruit tout sauf les variables locales de la fonction qui l'a appelé ainsi que toutes les fonctions imbriquées en cours jusqu'à la fonction main().
    Une règle simple à savoir :
    - en C : on ne doit jamais appeler exit()
    - en C++ : on ne doit jamais jamais appeler exit()

    Cette fonction permet de sortie en urgence. Comme tu l'a écris c'est moins grave d'oublier des variables en C.
    En C++, la sortie d'urgence se fait par un throw qui sera intercepté dans main, et le throw s'il est "catché" garanti qu'il détruira toutes les variables automatiques. Si on voulait une sortie d'urgence propre (autant que aie un sens!) on "catcherait" ça dans main() qui ferait alors un simple return. Note qu'appeler exit() dans main() est un énorme non sens, car un return fait exactement la même chose sauf qu'en plus il garantit qu'il détruit aussi les variables locales du main().

  6. #6
    Membre habitué
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2008
    Messages : 289
    Points : 151
    Points
    151
    Par défaut
    Bonjour et merci pour vos réponses.
    Je n'avais jamais lu cette page de doc sur exit(). Mea culpa.
    J'avoue que l'appel à exit() pour sortir du main() en C, je l'avais interprété tel quel suite à un cours sur la gestion des processus.
    Encore merci.

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

Discussions similaires

  1. Relation de composition cardinalité (1 <-> 1)
    Par PhilBrest dans le forum W4 Express
    Réponses: 7
    Dernier message: 26/01/2010, 17h26
  2. Réponses: 5
    Dernier message: 22/05/2008, 13h29
  3. [DC] Relation/Agrégation/Composition sur Client->Adresse
    Par amazircool dans le forum Diagrammes de Classes
    Réponses: 15
    Dernier message: 15/01/2008, 12h27
  4. Implementer une relation de composition en Orienté objet
    Par foufa007 dans le forum Diagrammes de Classes
    Réponses: 1
    Dernier message: 11/04/2007, 19h34
  5. [Débutant] Choix entre attribut par relation & aggrégation/composition ?
    Par GrandFather dans le forum Diagrammes de Classes
    Réponses: 14
    Dernier message: 04/12/2006, 10h12

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