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 :

Question sur le RAII


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2020
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Santé

    Informations forums :
    Inscription : Février 2020
    Messages : 12
    Points : 0
    Points
    0
    Par défaut Question sur le RAII
    bonjour
    je suis sur un tutorial à propos du RAII(j'ai download la page) et il y a une ambiguité à un endroit, je ne comprends pas la " modification dont parle celui qui a fait le tutorial "
    je vais copier coller tout le tuto et je cite "Un petit problème subsiste : les fonctions aBesoinDeTraitement et traiterObjet ont besoin d’un pointeur vers Objet et non d’un ObjetCPP. Mais il est relativement simple d’adapter le code pour qu’il fonctionne. " >>> et là quelque chose n'est pas clair et ambigu par rapport à cette modification à effectuer.

    La plupart du temps, les bibliothèques C bien écrites permettent de créer des objets via une fonction createObjet, objets qu’il faut ensuite libérer en utilisant une fonction freeObjet.

    Lorsqu’on souhaite utiliser un tel objet, on a un code qui peut ressembler à cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main()
    {
        auto objet = createObjet();
     
        // on utilise notre objet
     
        freeObjet(objet);
    }
    Ce code a un énorme défaut : il faut toujours penser à libérer notre objet en appelant la méthode freeObjet. C’est déjà source d’erreur. Mais surtout, il faut veiller à ce que cette méthode soit appelée dans tous les chemins d’exécution possibles. Imaginons le code qui suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void traitement()
    {
        auto tableau = std::vector<int>{};
        auto objet = createObjet();
     
        tableau.at(0) = 7;
     
        freeObjet(objet);
    }
    Ici, la ligne tableau.at(0) = 7 envoie une exception. Cette exception n’est pas attrapée. La méthode freeObjet n’est pas appelée.

    Autre cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int traitement()
    {
        auto objet = createObjet();
     
        if(!aBesoinDeTraitement(objet)) return 0;
     
        auto resultat = traiterObjet(objet);
     
        freeObjet(objet);
     
        return resultat;
    }
    Ce code vous paraît-il correct ? On a bien pensé à libérer la mémoire dans le cas où le traitement est effectué, mais pas dans le cas du if qui retourne 0. Ce code entraîne donc une fuite de mémoire dans le cas où l’objet n’a pas besoin d’être traité.

    Le RAII à la rescousse
    Mais alors quelle est la solution ? Comment faire en sorte que la ressource soit toujours libérée, quoi qu’il arrive ?

    Ce que vous savez peut-être déjà, c’est que pour un objet alloué de façon statique, dans la pile, le destructeur est toujours appelé. C’est pour cette raison qu’une bibliothèque (bien faite) en C++ ne nécessite jamais d’appeler manuellement une méthode de libération de ressource :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int traitement()
    {
        auto tableau = std::vector<int>{};
        auto objet = ObjetCPP{};
     
        if(!aBesoinDeTraitement(objet)) return 0;
     
        tableau.at(0) = 7;
     
        auto resultat = traiterObjet(objet);
     
        return resultat;
    }
    Dans le code précédent, avec ObjetCPP une classe C++ bien faite, le destructeur est appelé quoi qu’il arrive : dans le cas où l’objet n’a pas besoin de traitement et ensuite malgré le fait qu’une exception est lancée par la ligne tableau.at(0) = 7;.

    En quoi consiste donc le principe RAII ? Simplement à utiliser ce mécanisme systématiquement lors de l’acquisition de ressource, en encapsulant toutes les ressources dans des classes dédiées à l’acquisition et la libération de chacune d’elles. En d’autres termes, dans notre cas, on peut écrire le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class ObjetCPP {
        public:
            ObjetCPP() {
                ressource = createObjet();
            }
     
        protected:
            ~ObjetCPP() {
                freeObjet(ressource);    
            }
     
        private:
            Objet* ressource;
    };
    Et maintenant, si on utilise toujours ObjetCPP et plus Objet*, on n’aura plus jamais de fuite de mémoire !

    Vous remarquerez que le destructeur est protected (pour rappel, un destructeur doit être protected ou virtual, cf l’une des règles du NVI dans le tuto précédent. J’écrirai peut-être prochainement un article sur cette règle en particulier).

    Un petit problème subsiste : les fonctions aBesoinDeTraitement et traiterObjet ont besoin d’un pointeur vers Objet et non d’un ObjetCPP. Mais il est relativement simple d’adapter le code pour qu’il fonctionne.

    >>>>>>>>>> quel est cette modification ? j'attends la réponse en vous remerciant.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Comme on n'a même pas ni la déclaration ni la définition de ces 2 fonctions ni les choses qui ont été abordées précédemment dans le tutoriel, on ne peut faire que des suppositions à 2 balles.

    Voilà la mienne : passage par référence non const.

    signature des méthode avant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    bool aBesoinDeTraitement(Objet* toto);
    int traiterObjet(Objet* toto);
    signature des méthode après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    bool aBesoinDeTraitement(ObjetCPP& toto);
    int traiterObjet(ObjetCPP& toto);
    Mais bon, utilisez des pointeurs nus dans ce type d'exemple, c'est donner le "mauvais exemple".

    P.S.: "smart pointeur + deleter custom", j'y crois pas, il aurait présenté les smart pointeurs avant de donner des exemples tout pourri de librairie "C".

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2020
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Santé

    Informations forums :
    Inscription : Février 2020
    Messages : 12
    Points : 0
    Points
    0
    Par défaut
    ces tutos sont ici:
    https://koor.fr/Cpp/RAII/Index.wp
    j'étais au java et j'aime vraiment plus ça, les api comme hibernate etc.. les sgbd etc.. ça me soule.
    alors j'ai repris c/c++ que j'avais un peut commencé y'a très longtemps et concernant la libération de
    ressources par le raii: je suis un peut perplex et je vais voir d'autres tutos sur le sujet, les siens m'ont
    parfois aidé mais pas toujours alors......
    merci

  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
    Je ne vois pas le code posté dans ce tutoriel

    Citation Envoyé par suzut Voir le message
    je suis un peut perplex
    Pourquoi ? explique.

    1 truc me dérange dans le code
    Ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main()
    {
        auto objet = createObjet();
     
        // on utilise notre objet
     
        freeObjet(objet);
    }
    C'est du pur code C 1 peu mal fait.
    Je ne parle pas de la faute "createObject" et "freeObject" (mélanger le français et l'anglais )

    C'est du pur code C parce que lorsqu'on crée des structures struct, on crée en même temps 1 interface : createXXX, deleteXXX, initXXX, updateXXX, ...
    Tout ceci afin d'éviter de copier-coller X fois 1 même code très difficilement trouvable avec la recherche (en cas de modifications) : 1 seul endroit dans le code pour répercuter les modifications partout.

    1 peu mal fait, parce qu'on met le nom de la classe à gauche (c'est + 1 préférence personnelle ou dans les coding styles) : object_create, object_delete, object_init, object_update, ...

    Donc je ne vois pas pourquoi cette interface (1) createObject et freeObject se retrouve telle quelle dans le constructeur et le destructeur
    C'est d'ailleurs ce qui fait office de constructeur et de destructeur en C surtout que le code de (1) doit faire appel à malloc et free.

    Après il y a la notion de "lazy initialisation" : en gros l'initialisation de la ressource ne se fait pas dans le constructeur.

    Sais-tu qu'à chaque fois qu'on utilise 1 objet sans pointeur ni référence (paramètre, variable locale, ...), 1 objet est créé ?
    Et donc si on met l'initialisation dans le constructeur, tu construis beaucoup [beaucoup] de ressources.


    Citation Envoyé par suzut Voir le message
    pour rappel, un destructeur doit être protected ou virtual, cf l’une des règles du NVI dans le tuto précédent. J’écrirai peut-être prochainement un article sur cette règle en particulier
    La notion de protected et de virtua sont 2 notions distinctes : l'une n'empèche pas l'autre.
    Surtout que cela va dépendre si tu protèges le destructeur de la classe mère, des classes filles ou de tout le monde.

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2020
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Santé

    Informations forums :
    Inscription : Février 2020
    Messages : 12
    Points : 0
    Points
    0
    Par défaut
    arrrr !!!! je m'étais trompé de liens GRR désolé :/ c'était ici le code :
    https://nodatek.com/article10/tuto-cpp-le-raii
    & du coup la page s'affiche plus; j'ai testé avec 2 ip; en espèrant que le server se réveillera....

    pour répondre à la question "Sais-tu qu'à chaque fois qu'on utilise 1 objet sans pointeur ni référence (paramètre, variable locale, ...), 1 objet est créé ?
    Et donc si on met l'initialisation dans le constructeur, tu construis beaucoup [beaucoup] de ressources. " ......
    oui, on m'a conseillé d'utiliser les pointeurs ou les références plutôt que les constructeurs par copy

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Bon bin, le tutoriel aiguille sur les smart pointeurs et la STL, donc c'est cool.

    Les exemples "en C" sont un peu tout pourri mais c'est un peu un argumentaire à base d'"homme de paille".

    On est sur un tutoriel, pas sur un argumentaire béton contre les vieilleries du C ou du C++ pré-98.

    Et si le C++ avait des choses, en standard, aussi aboutis qu'Hibernate (ou autres ORMs), ça serait trop cool.

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2020
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Santé

    Informations forums :
    Inscription : Février 2020
    Messages : 12
    Points : 0
    Points
    0
    Par défaut
    ah oui je vois, un prof de Reuilly Diderot m'avait dit aussi ça par mail; "le c/c++ n'est pas standardisé comme java"(...) les gui déjà prêt etc... new GridLayout svp !
    maintenant j'ai mis qu creator sur 1 kali linux et je vais essayer de compiler la version open-source, il me manque l'étape
    du "make install" il a fait des répertoires quasiment vide sur la destination :/
    & j'ai pas bien capté la dans les paramètres de QT: comment déployer un exe pour windobe... bon bah je risque pas d'en avoir terminé

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    ah oui je vois, un prof de Reuilly Diderot m'avait dit aussi ça par mail; "le c/c++ n'est pas standardisé comme java"(...) les gui déjà prêt etc... new GridLayout svp !
    Bon bin, déjà C/C++, ça n'existe pas, les comparaisons avec Java, c'est nimportnawak.

    La norme C, elle existe au moins depuis 1989, d'où le C89 (mais vraisemblablement antérieure, voir sous forme de standards (de fait) et pas encore de norme)
    La norme C++, elle existe depuis 1998, d'où le C++98.

    Java n'a jamais été normalisée avant le rachat de Sun Micro System par Oracle, dans les années 2009. Sun ne publiait que les spécifications du langage et des JVM, rien de normatif.
    Je sais même pas si tout ce bordel a fini par pondre une "norme" ou juste des standard de fait à la con.
    Les victimes des spécifications différentes entre les OpenJDK vs les OracleJDK, comme moi, sont amères.
    Donc parler de "norme" pour Java, ça me fait sourire (mais pas rire).

    Qt et QT, ça n'a rien à voir. (Google est ton ami)

    & j'ai pas bien capté la dans les paramètres de QT: comment déployer un exe pour windobe... bon bah je risque pas d'en avoir terminé
    Le "spécialiste" windobe ricane en lui quand il voit la jungle des "déployeurs" Linux engloutir un "admin" trop optimiste.

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2020
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Santé

    Informations forums :
    Inscription : Février 2020
    Messages : 12
    Points : 0
    Points
    0
    Par défaut
    ah oui, 89 très bonne année et google boarf... pas réellement.

  10. #10
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2020
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Santé

    Informations forums :
    Inscription : Février 2020
    Messages : 12
    Points : 0
    Points
    0
    Par défaut
    ouaip, j'aurais pas du écrire "c/c++" : quel connerie putain... depuis les cours de c en 97 avec le captain Haddock: ça parlait bien de Kernighan and Ritchie puis d'ANSI;
    Jean-Baptiste Yunès disait en fait: " Pour C++, c’est pire, c’est un langage très difficile à maitriser et les GUIs en C++ ne sont pas normalisées, habituellement on utilise Qt. Je ne saurais le recommander." il s'est passé quelques années depuis 1997 avant que je reprenne la programmation que j'avais commencé avant de partir à l'armée mais j'y travail, avec l'herboristerie(ça c'est mon amie) en soutien ça devrait aller

  11. #11
    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
    Citation Envoyé par suzut Voir le message
    comment déployer un exe pour windobe...
    Je vais te faire la version courte :

    En gros Qt est payant mais les anciennes versions sont gratuites : regarde sur cette page Qt Downloads.
    Et à cause de la licence de Qt, tu ne peux pas compiler en statique (tout à l'intérieur de l'exécutable).
    Résultat : avec l'exécutable tu dois te trimbaler la palanquée de DLL Qt.

  12. #12
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2020
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Santé

    Informations forums :
    Inscription : Février 2020
    Messages : 12
    Points : 0
    Points
    0
    Par défaut
    hhhhhhhhhhhh c'est vraiment con alors... donc inutile que j'essaye de compiler encore la version opensource, créer un exe static/"portable" est donc pas possible... j'ai la 5.12 sous kali et pu la peine de chercher des tutos pour créer un exe indépendant si c'est foutu... ah ! comme tout ça est réjouissant et agréable.

  13. #13
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2020
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Santé

    Informations forums :
    Inscription : Février 2020
    Messages : 12
    Points : 0
    Points
    0
    Par défaut
    et avec eclipse CDT c'est pas la peine non plus d'essayer d'implanter un gui et obtenir des exe static je suppose...
    mon cousin m'avait dit d'importer des "librairies du bureau de linux", super.. lesquelles je vois pas... en tout cas, c'est tendu

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

Discussions similaires

  1. [debutant] Questions sur 1 futur projet
    Par cyrull22 dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 28/04/2003, 21h49
  2. Quelques questions sur le TWebBrowser...
    Par CorO dans le forum Web & réseau
    Réponses: 3
    Dernier message: 17/01/2003, 21h23
  3. Question sur les handles et les couleurs...
    Par MrDuChnok dans le forum C++Builder
    Réponses: 7
    Dernier message: 29/10/2002, 08h45
  4. Réponses: 2
    Dernier message: 11/08/2002, 21h27
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11

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