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 :

Libération variable Null ou Delete


Sujet :

C++

  1. #1
    Membre averti Avatar de LeonCosnyd
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 439
    Points : 368
    Points
    368
    Par défaut Libération variable Null ou Delete
    Bonjour,

    J'ai une question un peu bête mais je préfère avoir une réponse claire !

    J'utilise un pointeur que je déclare comme ceci :
    Dans mon code je l'initialise avec cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monObjet = new maClasse();
    J'ai besoin de réinitialiser mon pointeur pour pouvoir le réutiliser un peu plus loin ! Je me demande donc si je fais la bonne technique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    monObjet = NULL;
    monObjet = new maClasse();
    Je me demande si la première allocation que j'ai fait à été libéré ? Ou dois-je faire un delete avant ? Mais si je delete monObjet le pointeur est-il toujours utilisable après ?
    Google est ton ami !

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Normalement, tu dois faire un delete avant.

    Mais ça, c'est le vieux C++. Depuis C++11, tu peux faire ça à la place:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unique_ptr<monObjet> = new maClasse();
    Et en C++14, la formule recommandée, c'est ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unique_ptr<monObjet> = make_unique<maClasse>();
    Le unique_ptr<> se charge de la destruction de l'objet pointé.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti Avatar de LeonCosnyd
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 439
    Points : 368
    Points
    368
    Par défaut
    unique_ptr<monObjet> = make_unique<maClasse>();
    Je ne savais même pas qu'il était possible de faire une gestion automatisée de la mémoire en C++ ! Car là il s'agit bien d'un fonctionnement similaire à un garbage collector (certes pour une variable) ???

    Merci pour l'info !
    Google est ton ami !

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 963
    Points
    32 963
    Billets dans le blog
    4
    Par défaut
    Non il s'agit juste d'utiliser une classe et une variable membre, ainsi que la surcharge d'opérateur pour l'affectation, et profiter du mécanisme de destructeur appelé automatiquement quand la portée de la variable est dépassée.
    make_unique allant un peu plus loin en assurant d'être exception-proof, et peut-être d'autres subtilités
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par LeonCosnyd Voir le message
    Car là il s'agit bien d'un fonctionnement similaire à un garbage collector (certes pour une variable) ???
    Non, c'est juste un objet avec:
    1. Un destructeur qui fait un delete sur le pointeur contenu.
    2. Une sémantique de transfert faite correctement cette fois-ci (contrairement à auto_ptr où c'était fait maladroitement) grâce à une amélioration du langage lui-même.


    En fait, dans C++11, les trois améliorations majeures du langage lui-même sont:
    1. La sémantique de transfert supportée par le langage (les classes peuvent dorénavant avoir un constructeur de déplacement en plus du constructeur de copie).
    2. Les variadic templates (templates à nombres de paramètres variables; c'est ce qui permet de faire des wrappers "parfaits" de fonction, et c'est utilisé pour make_unique<> mais pas seulement)
    3. Les expressions lambda, qui ne sont pas utilisées dans le cadre de cette discussion mais ont leur utilité.

    Ensuite, la bibliothèque standard a reçu diverses améliorations, dont la plupart dépendent directement des améliorations du langage:
    • Le unique_ptr<>;
    • le template function<> qui harmonise et simplifie tout le système de foncteurs et pointeurs de fonction;
    • le support natif du multithreading via la classe thread;
    • le support natif de la génération de nombres aléatoires (je ne crois pas que celui-ci dépende d'une amélioration du langage)
    • etc.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

    Informations professionnelles :
    Activité : aucun

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

    En fait, les pointeurs intelligents sont ce qu'il convient d'appeler des "capsules RAII", car elles applique le (très mal nommé à mon sens) principe du même nom (RAII).

    Ce principe est en réalité l'acronyme (tu le sais surement, les développeurs adorent ce genre de choses ) de Ressource Acquisition Is Initialisation et part du principe que lorsque tu crées une données qui a besoin d'une ressource, le simple fait de créer ta donner doit s'assurer que la ressource dont elle a besoin sera bel et bien disponible. (Tu remarqueras au passage que je viens à peu près de t'expliquer le fonctionnement classique que l'on peut observer pour à peu près n'importe quel constructeur ). C'est grâce à ce principe que l'on peut depuis déjà bien longtemps avoir un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main(){
        std::ifstream ifs("fichier.txt");
        /* ici, le fichier a été ouvert et est utilisable, ou bien, ifs est dans un état invalide
         * et le test échoue
         */
        if(ifs){
            /* génial, on peut continuer */
       } 
    }
    Mais cet accronyme va plus loin, car, il y a toujours une sorte de "jeu en miroir" : si quelque chose se fait à la création, c'est sans doute qu'il y a "quelque chose" qui pourra le défaire à la destruction. Ainsi, le RAII stipule que toutes les ressources dont "quelque chose" est propriétaire devront être correctement détruite ... lorsque ce quelque chose est détruit.
    Modifions un peu le code que je viens de donner afin de comprendre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int main(){
        if(someTest){
            std::ifstream ifs("fichier.txt");
            /* ici, le fichier a été ouvert et est utilisable, ou bien, ifs est dans un état invalide
             * et le test échoue
             */
            if(ifs){
                /* génial, on peut continuer */
        }
       } // ifs est automatiquement détruit ici
       return 0;
    }
    Le RAII nous donne la garantie que, lorsque ifs est détruit, les ressources matérielles que la classe std::ifstream utilise en interne seront correctment libérées. Dans le cas présent, nous aurons par exemple entre autre la certitude que le "lock" éventuellement placé par le système d'exploitation sur le fichier "fichier.txt" sera bel et bien levé, et ce, sans avoir quoi que ce soit à faire.

    L'énorme avantage, c'est que les développeurs ne valent souvent pas mieux que n'importe quel utilisateur, et c'est tout à fait normal : ce sont eux même des utilisateurs. Et, en tant que tel, il faut les considérer comme des "imbéciles distrait". Et ne crois pas que je me considère meilleur qu'un autre à ce sujet là (je ne suis d'ailleurs pas loin de penser que les meilleurs développeurs sont ceux qui sont conscients de cette faiblesse et qui mettent tout en oeuvre pour éviter les catastrophes qu'elle peut engendrer )

    Enfin, revenons à nos moutons : les pointeurs intelligents vont appliquer le même principe et s'assurer que la mémoire allouée au pointeur sous jascent sera effectivement libérée exactement au moment opportun, c'est à dire:
    • lorsque la variable de type std::unique_ptr sera détruite (parce qu'on sort de sa portée, ou parce qu'on la retire de la collection qui la contient)
    • lorsque le dernier std::shared_ptr référençant la mémoire allouée au pointeur sous-jascent sera détruit (parce que l'on sort de sa portée ou parce qu'on le retire de la collection qui la contient)

    Cela n'a donc absolument rien à voir avec un quelconque mécanisme de Garbage Collector: typiquement, le garbage collector va parcourir la liste des références qui existent pour savoir si elles sont encore utilisées, et ne supprimer que celles pour lesquelles ce n'est plus le cas; ce qui occasionne (allez, soyons sympa : qui peut occasionner) un "léger retard" (parfois même "pas si léger que ca" d'ailleurs) entre le moment où la référence à supprimer cesse d'être utile et le moment où elle est effectivement supprimée.

    Les pointeurs intelligents vont quant à eux occasionner la libération immédiate de la mémoire allouée au pointeur sous-jacent. Ainsi, si tu as un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int main(){
       for(int i= 0;i<10;++i){
          auto ptr = std::make_unique<int>(i);
          std::cout<<*(ptr.get())<<"\n";
       } // on sort de la portée de ptr, ptr est donc détruit
       return 0;
    }
    lorsque ptr est détruit, la mémoire allouée au pointeur sous-jacent est directement libérée elle-aussi
    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 confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Mai 2012
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2012
    Messages : 163
    Points : 624
    Points
    624
    Par défaut
    Citation Envoyé par koala01 Voir le message
    En fait, les pointeurs intelligents sont ce qu'il convient d'appeler des "capsules RAII", car elles applique le (très mal nommé à mon sens) principe du même nom (RAII).
    Salut,

    Merci pour cette explication claire du RAII. Cependant, il me semble que le RAII et les pointeurs intelligents sont quand même assez orthogonaux.

    Le RAII permet de lier le cycle de vie d'une ressource à celle d'un objet (http://en.cppreference.com/w/cpp/language/raii). Ça correspond donc à la construction/destruction et ça s'utilise avec ou sans pointeur intelligent.

    Les pointeurs intelligents permettent de gérer la durée de vie des objets et ça s'applique "avec ou sans RAII à l'intérieur de l'objet".

    Maintenant, c'est vrai qu'on peut considérer qu'un attribut est déjà une ressource et qu'il y a donc toujours du RAII. De plus, effectivement, un pointeur intelligent va automatiquement lancer la destruction et donc indirectement terminer le RAII. C'est peut-être cela que tu appelles "capsule RAII" (cppreference parle de "RAII wrapper"). Mais le RAII existe également sans pointeur intelligent.

    Et pour les shared_ptr, ce n'est effectivement pas du "garbage collector" mais plutôt du "reference counting" déterministe (comme en python je crois).

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    On peut avoir tu RAII hors des pointeurs intelligents bien sûr, mais en C++, on ne peut pas avoir de pointeurs intelligents sans RAII.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Mai 2012
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2012
    Messages : 163
    Points : 624
    Points
    624
    Par défaut
    Oui, c'est ce que je voulais dire par :

    Maintenant, c'est vrai qu'on peut considérer qu'un attribut est déjà une ressource et qu'il y a donc toujours du RAII. De plus, effectivement, un pointeur intelligent va automatiquement lancer la destruction et donc indirectement terminer le RAII.
    Et si, tu peux avoir des pointeurs intelligents sans RAII. Exemple (de ce qu'il ne faut pas faire) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct A {
        int * p;
        A() { p = new int; }
        // pas de destruction de p => pas de RAII pour p
    };
     
    int main() {
        unique_ptr<A> a = make_unique<A>();  // indirectement, RAII incomplet
        return 0;
    }
    On aurait également le problème avec un objet classique (sans le pointeur intelligent) et c'est pour ça que je dis que RAII et pointeur intelligent sont relativement orthogonaux (les pointeurs intelligents gérent la durée de vie de l'objet pointé mais pas les ressources internes de l'objet).

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    La partie non-RAII de ton code ne fait pas partie du pointeur intelligent, ça ne suffit donc pas à dire qu'on peut avoir un pointeur intelligent sans RAII.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par LeonCosnyd Voir le message
    Je ne savais même pas qu'il était possible de faire une gestion automatisée de la mémoire en C++ ! Car là il s'agit bien d'un fonctionnement similaire à un garbage collector (certes pour une variable) ???
    Contrairement aux autres réponses, je répondrais plutôt "oui" à cette question. Il s'agit bien là d'un mécanisme de type garbage collection, même s'il possède des caractéristiques assez différente des garbage collectors qui peuvent exister en Java et en C# par exemple. Les principales différences sont les suivantes :

    • Tu choisis pour chaque objet le mode de collection qui sera le plus approprié au moment de sa construction (géré sur la pile, dans un conteneur, par unique_ptr, par shared_ptr...), là où en Java/C#, il existe un mécanisme unique pour tous les objets (c'est un peu plus de travail, mais ça apporte des choses intéressantes en terme de perfs)
    • Ces mécanismes sont déterministes : On sait quand une ressource sera libérée, et on sait qu'elle sera libérée. Ce qui n'est pas le cas en Java/C#. Une conséquence est qu'on peut mettre du code intéressant dans les destructeurs, là où les finalizers sont globalement inutiles, et où d'autre mécanismes moins élégants ont dû être utilisés (les using du C#, les try-with-resources du Java)
    • Ces mécanismes sont à manier avec précaution quand on a des boucles, là ou un garbage collector classique gère les boucles sans soucis
    • Ces mécanismes sont plus économes en mémoire. Leur impact en performance est différent (il y a des cas où un garbage collector sera plus efficace, mais c'est assez rare).



    Régulièrement quand je dis "C++" à des développeurs Java, ils me répondent "ah, oui, le langage où il faut libérer la mémoire soi-même". Et ça a tendance à m'agacer, car ça montre que ces gens là critiquent non pas le C++ tel qu'il est (et pourtant, il y en aurait des critiques recevables !..), mais une image totalement faussée de ce langage, qui était peut-être vraie il y a 20 ans. Ça fait des années que dans du code à moi (par opposition à du code existant où je fais juste une micro-modification), je n'ai pas écrit un seul delete.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  12. #12
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Mai 2012
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2012
    Messages : 163
    Points : 624
    Points
    624
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    La partie non-RAII de ton code ne fait pas partie du pointeur intelligent, ça ne suffit donc pas à dire qu'on peut avoir un pointeur intelligent sans RAII.
    À mon avis, tu confonds la durée de vie d'un objet et celle de ses ressources internes.
    Un pointeur intelligent gère la durée de vie de l'objet alors que le RAII concerne les ressources internes. Il s'agit de deux niveaux différents et qui ne sont pas si interdépendants que tu sembles le dire.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    C'est bien pour cela que j'ai parlé de capsule RAII...

    En fait, j'aurais du dire que les pointeurs intelligents permettent d'appliquer le (et plus précisément de terminer l'application du) RAII sur les ressource dont la pratique a fait que le développeur normalement pris la responsabilité de la libération.

    En effet, un appel à new (ou new[]) impose que la ressource soit libérée par delete (respectivement delete[]) "au plus tard avant de perdre définitivement toute référence à cette ressource".

    Or, appliquer le RAII manuellement sur ce genre de ressource est pour le moins hasardeux:
    1. Si on ne fait pas une copie en profondeur, on observe un partage de la ressource qui occasionnera plusieurs tentatives de libération de celle-ci
    2. Si on ne pense pas à faire en sorte que l'élément qui demande l'allocation de la ressource veille à la détruire lorsqu'il est détruit, on obtient une fuite mémoire
    3. Si on essaye de détruire cette ressource d'une autre manière, il devient rapidement difficile de prévoir tous les chemins d'exécution possible, ne serait-ce que parce que le lancement d'une exception créera un chemin alternatif
    4. Si l'élément est responsable de l'allocation plusieurs ressources par new (ou par new[]) et que l'une seule d'elles échoue il devient rapidement difficile de savoir lesquelles ont été allouées (et doivent être libérées) et lesquelles n'ont pas encore été libérées.
    5. Dans le cas de ressources multiples créées dans le constructeur, il faut savoir que si l'une d'elle échoue, une exception est lancée et l'objet en cours de construction est -- purement et simplement -- considéré comme non construit, si bien qu'il n'y aura aucune tentative de le détruire par la suite

    Maintenant, il est tout à fait vrai que les pointeurs intelligents ne peuvent appliquer le RAII que sur des ressources qui l'appliquent elles-même correctement en interne. Et c'est bien pour cela que l'on insiste pour que tout pointeur renvoyé par new (ou new[])soit directement pris en charge par un pointeur intelligent, ou mieux encore, qu'on fasse appel au fonction de création "sécurisée" de pointeurs intelligents.
    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

  14. #14
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par zobal Voir le message
    À mon avis, tu confonds la durée de vie d'un objet et celle de ses ressources internes.
    Un pointeur intelligent gère la durée de vie de l'objet alors que le RAII concerne les ressources internes. Il s'agit de deux niveaux différents et qui ne sont pas si interdépendants que tu sembles le dire.
    En l’occurrence, je pense plutôt que tu ne comprends pas le terme "capsule RAII" dans le même sens que Medinoc et des autres intervenants (qui est globalement le sens usuellement utilisé).
    Le terme RAII s'utilise vis à vis de la libération de nos propres ressources et non transitivement vis à vis des ressources de nos ressources.

    La capsule RAII qu'est le pointeur intelligent l'est vis à vis de l'objet qu'il référence. C'est précisément parce qu'il gère la durée de vie de l'objet pointé qu'il est une capsule RAII pour celui-ci

    Il garanti donc uniquement qu'à la destruction dudit pointeur, l'élément qu'il référence sera lui-même libéré et ne présume rien des ressources de cet objet référencé. Là on rejoint effectivement ton point de vue sur le rôle du pointeur intelligent mais, sauf à considérer qu'une classe qui libère ces ressources à la destruction n'applique pas le RAII car rien ne garanti que ces ressources vont bien libérer leurs ressources propres, ça en reste du RAII.

  15. #15
    Membre confirmé
    Profil pro
    Développeur informatique
    Inscrit en
    Mai 2012
    Messages
    163
    Détails du profil
    Informations personnelles :
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2012
    Messages : 163
    Points : 624
    Points
    624
    Par défaut
    Ok. C'est pour cela que j'avais fait cette remarque dans mon premier message :
    Citation Envoyé par zobal Voir le message
    ... C'est peut-être cela que tu appelles "capsule RAII" (cppreference parle de "RAII wrapper").
    De là à parler de sens "usuellement utilisé", ça me parait exagéré : le terme "RAII wrapper" n'apparait pas dans la norme et seulement très rarement dans les docs classiques (cppreference, isocpp, core guidelines...), parfois d'ailleurs pour un sens différent. Et à mon avis, c'est tant mieux car je ne vois pas vraiment l'intérêt d'un terme de plus pour un concept aussi évident, à part peut-être donner raison à la réputation de langage complexe du C++.

  16. #16
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par zobal Voir le message
    De là à parler de sens "usuellement utilisé", ça me parait exagéré : le terme "RAII wrapper" n'apparait pas dans la norme et seulement très rarement dans les docs classiques (cppreference, isocpp, core guidelines...), parfois d'ailleurs pour un sens différent. Et à mon avis, c'est tant mieux car je ne vois pas vraiment l'intérêt d'un terme de plus pour un concept aussi évident, à part peut-être donner raison à la réputation de langage complexe du C++.
    Sauf erreur de ma part, RAII tout court n'apparait pas dans la norme (en tout cas, je viens de chercher dans les versions 98 et 11 sans le trouver).

    Et c'est bien la notion de "capsule RAII" (RAII wrapper) qui est généralement utilisée pour désigner les objets encapsulant un autre objet - non-RAII mais possesseur de ressources - en lui apportant le RAII vis à vis de ses ressources.
    Après que ce terme apparaisse rarement n'est pas étonnant car il n'y a que peu d'objets de ce type (essentiellement les pointeurs intelligents pour les pointeurs et les verrous pour les mutex), la majorité des objets implémentant directement le RAII sans nécessiter de telles capsules.

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    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 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par gl Voir le message
    Et c'est bien la notion de "capsule RAII" (RAII wrapper) qui est généralement utilisée pour désigner les objets encapsulant un autre objet
    Oui et non ici on parle d'un pointeur nu C qui n'a pas les mécanismes C++ constructeur/ destructeur (au moins ceux là)

    Donc c'est normal d'utiliser une classe C++ et englobé ce pointeur nu C, classe qui va gérer ce pointeur.

    On le fait tout également avec un lock, mutex, handle, ...

  18. #18
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Et il ne me semble pas avoir dit autre chose, du coup j'ai du mal à comprendre le "oui et non" (au passage, la citation en coupant la fin de la phrase change pas mal le sens de la phrase. C'est assez maladroit)

  19. #19
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Citation Envoyé par gl Voir le message
    Après que ce terme apparaisse rarement n'est pas étonnant car il n'y a que peu d'objets de ce type (essentiellement les pointeurs intelligents pour les pointeurs et les verrous pour les mutex)
    et std::vector

  20. #20
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    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 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par gl Voir le message
    Et il ne me semble pas avoir dit autre chose, du coup j'ai du mal à comprendre le "oui et non" (au passage, la citation en coupant la fin de la phrase change pas mal le sens de la phrase. C'est assez maladroit)
    Parce que ce n'est pas un objet qui est encapsulé : ce sont soit des pointeurs soit des structures avec des pointeurs, mais en aucun cas des classes C++

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [MySQL] initialiser une variable à NULL
    Par papilou86 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 11/07/2008, 12h01
  2. probleme variable null non acceptée
    Par soccard dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 28/05/2008, 18h06
  3. [Tableaux] Fonction extract() sur des variables NULL
    Par Tchupacabra dans le forum Langage
    Réponses: 7
    Dernier message: 21/05/2008, 22h34
  4. Pb récuperation Variable NULL
    Par cracov02 dans le forum DB2
    Réponses: 2
    Dernier message: 28/04/2008, 15h29
  5. Probleme variable null
    Par florentino dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 06/07/2007, 15h53

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