LOCODUINO

Le monde des objets (2)

Des objets partout !

. Par : Dominique, Thierry

Visibilité, encapsulation Nous allons maintenant développer une petite classe qui va nous servir d’exemple très simple à comprendre, mais qui fera partie d’un ensemble plus ambitieux dans les chapitres suivants... Imaginons une Led, qui doit être initialisée avec un numéro de broche et qui peut s’allumer et s’éteindre, donc avec une (…)

Retourner à l'article

Vous répondez à :

Le monde des objets (2) 1er avril 2023 19:24, par Benoit92

Merci,
Je comprends pas tout, mais je m’accroche !.
Le format de aPin et aMontageInverse est implicitement défini par :
pin = aPin ;
montageInverse = aMontageInverse

Donc, pin étant déclaré en format byte (8 bits),
aPin est la variable qui peut potentiellement varier entre 0 et 1024.
C’est donc aPin qui est appelé dans certaines des fonctions.

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

23 Messages

  • Le monde des objets (2) 2 février 2015 20:38, par DDEFF

    Commentaire.Allumer()
    Merci Dominique et Thierry,
    Les esprits chagrins pourraient dire : tout ça pour allumer une LED...
    Mais, justement, parce que le problème est connu de tous, sa solution par les classes est très claire et facile à comprendre. Bravo !
    Commentaire.Eteindre()

    Répondre

    • Le monde des objets (2) 2 février 2015 22:29, par Dominique

      Je dois humblement avouer que c’est Thierry qui a tout écrit.
      Mon statut de co-auteur est minuscule !

      Répondre

  • Le monde des objets (2) 2 février 2015 20:42, par Thierry

    Merci.

    PS : tu as oublié d’initialiser ta classe avec Led Commentaire(13) ! :))

    Répondre

  • Le monde des objets (2) 22 avril 2017 07:55, par Denis

    Bonjour, je suis très en retard au vue de la publication mais je suis complètement séduit par cette approche de la programmation objet en C++.
    Bravo à vous.
    Juste une remarque pour voir si j’ai bien compris, pour la méthode Rafraichir() lorsque vous écrivez
    digitalWrite(pin, Etat ^ aMontageInverse) ne faut-il pas écrire plutôt
    digitalWrite(pin, etat ^ aMontageInverse) i.e la variable "état" sans majuscule ??
    Et deuxième petite question, est-ce une bonne pratique de commencer toutes les méthodes par des majuscules (Raffraichir(), Eteindre(), etc...) ?? ou ne doit-on pas réserver ceci au constructeur de la classe ?
    Merci encore pour cet article et les autres bien sur.

    Répondre

    • Le monde des objets (2) 13 janvier 2018 10:32, par Thierry

      Bonjour

      Avec presque trois ans de retard, je vais quand même répondre aux questions !

      La ligne devrait en fait être
      digitalWrite(pin, etat ^ montageInverse);
      Merci de me l’avoir fait remarquer. C’est corrigé dans l’article.

      Pour les majuscules sur les noms de fonction, c’est une question de conventions. Il n’y a pas de règle établie, vous faites ce qui vous semble juste. De mon côté, les fonctions ont toujours une majuscule pour commencer. Les seuls noms qui commencent par une minuscule sont les variables locales (internes à une fonction) et les données membres privées :

      class test
      {
       public:
         int Toto;
      
       private:
         int titi;
      
       public:
         void Fonction(int aTutu);
      
       private:
         void FonctionInterne();
      };
      
      void test::Fonction(int aTutu)
      {
        int tete = 0;
      
        tete = aTutu;
        titi = tete * 2;
      
      // ou mieux
      
        this->titi = tete * 2;
      }

      Tout est question d’habitudes, de conventions, de règles entre développeurs lorsque vous faites partie d’un groupe comme c’est mon cas au boulot ou ici. L’intérêt de ces règles est de permettre une relecture facile et une compréhension plus rapide du code lu.

      Répondre

      • Le monde des objets (2) 6 février 2020 00:54, par eddymaue

        bonjours ... ques années plus tard

        c’est vrai que tout est convention et les règles on les établis pour soi même en premier lieu et si on travail en groupe ... le tout est décidé en groupe... je viens du monde Visual foxpro et j’ai travaillé dans ce merveilleux environnement plus de 20 ans.... Ce que j’ai retenu de cette communauté c’est
        que la préfixation a été adopté comme commune à tous. Que nous soyons français, anglais, allemand, italien, chinois, japonais ou latino d’Amérique latine ... on a tous adopté la meme convention... et ca c’est grace leader de la communauté Visual Foxpro.

        Dans le monde de l’arduino il n’y a aucune convention autre que la déclaration global des objets, des variables et des entêtes... Ce qui fait que 500 ligne plus loin la variable Pin, comme exemple, est de type integer sans savoir s’y elle est propre à une classe, une structure ou d’un type déclaré. On sait que Pin est integer parce qu’on l’a déclaré 5 ligne plus hautes... j’appelle cela du code anarchique

        voilà de quoi à méditer ... et si vous l’essayer vous risquez de l’adopter

        si j’écris
        int giPin1 = 5

        ’g’ pour globale
        parce que accessible globalement partout dans le code et, bien sur, cette variable est déclarée avant void setup()

        ’i’ pour integer
        représente le type déclaré de la variable

        char gcChoix : global et caractère
        comme exemple un choix de menu

        dans mon cas tout ce qui est dans une classe
        g pour global
        p pour private ou protégé

        et a cause de l’intellisence de PIO ou VS communauty dans mes classe je fais comme suivant

        je préfixe comme suivant
        a pour attribut
        f pour fonction


        class test

        public :
        int giToto ;

        private :
        int a_piTiti ;

        public :
        void fgMaFonction(int tiTutu) ;

        private :
        void fpMaFonctionInterne() ;
         ;

        void test::fgMaFonction(int tiTutu) // nous avons préfixé par ’t’ pour paramètre pour ne pas confondre avec ’p’ qui veut dire privé ou protégé

        int liTete = 0 ; l pour local

        liTete = tiTutu ;
        a_piTiti = liTete * 2 ;

        // ou mieux

        this->a_piTiti = litete * 2 ;

        bon je nouveau dans le monde arduino, 1 an. Il s’est tant écrit avant moi, et il s’en écrira beaucoup après moi

        je n’ose croire que je réussisse à influencer qui que ce soit... c’est la vie. Mais si un jour je tombais sur du code usant d’une préfixation .... je lèverai un pouce

        Répondre

        • Le monde des objets (2) 6 février 2020 08:44, par jean-luc

          Bonjour.
          je ne connais pas visual foxpro et j’ai donc cherché en quoi consiste ce langage.
          visiblement il s’agit d’un langage de script non typé. Je comprends donc que vous prefixiez à tout va car c’est le seul moyen de retrouver ses petits.
          C et C++ ne sont pas des parangons du typage mais ils font raisonnablement le travail et le compilateur vous signalera des mélanges de pinceaux dans les variables de types différents.
          On peut préfixer pour noter le scope mais préfixer pour le type de données n’est pas utile.
          Par ailleurs je ne suis pas fan de ce que j’appellerai la sur-notation comme par exemple l’usage de this->. Certes cela permet de s’assurer que la variable qui nous intéresse est bien membre de l’objet et n’est pas une globale mais avec de la lourdeur qui nuit à la lisibilité du code, tout comme les préfixes qui sont de plus d’une lettre. D’ailleurs si on programme sans variable globale, le problème n’existe pas.

          Répondre

  • Le monde des objets (2) 1er septembre 2017 09:12, par debutante69

    Bonjour,
    Je découvre Arduino et ses subtilités et merci pour vos articles très bien expliqués.
    .
    Cependant, est-ce que l’ accolade point-virgule à la ligne 17
    ne devraient-ils pas être
    à la ligne 56 /// fin de la classe Led , avant le commentaire ?
    .
    PS : je ne suis pas arrivé à représenter l’accolade

    Répondre

    • Le monde des objets (2) 1er septembre 2017 14:26, par Thierry

      Il est en effet possible de coder toutes les fonctions directement dans la déclaration de la classe, mais ce n’est pas la façon de faire adoptée ici. Si la classe avait été incluse dans un fichier hpp et utilisée à divers endroits, le premier source compilé n’aurait pas posé de problème, mais le deuxième et les suivants auraient rouspété en signalant que les fonctions de la classe décrite et codées dans le hpp existaient déjà ! En séparant la classe de ses fonctions, on évite le problème. Et puis une fonction incluse dans une déclaration de classe est potentiellement ’inline’ au bon vouloir du compilateur, c’est un risque que je n’ai pas voulu courir. Une fonction ’inline’ est une fonction dont l’appel sera remplacé par son code avant la véritable compilation. Mais si le code en question est un peu lourd, le multiplier par autant d’appels va grever la mémoire programme, et ce peut être un problème.

      Répondre

  • Le monde des objets (2) 17 décembre 2017 20:18, par Eric

    Bonjour,

    Tout d’abord, je "bosse" sur raspberry, mais je ne vois pas de grosses différences avec l’arduino, excepté la fonction setup() et loop() dont on ne peut se passer sur celui ci.
    Grace a vous, j’ai pu enfin adapter mon code c, qui gère les interruptions, en POO.
    J’ai donc deux types de classes, une Actionneur et une Capteur.
    Au niveau de la classe Capteur, je souhaiterai ajouter une propriété privée qui est l’adresse de la routine d’interruption, qui est passée en paramètre lors de la création de l’objet.
    Mais je ne sais pas comment m’y prendre.
    Pour que mon programme fonctionne je suis obligé de passer l’adresse de la routine d’interruption dans la méthode conf qui elle est publique.
    je ne sais pas d’où vient le problème mais aléatoirement lorsque j’allume un relai (avec un bouton), une led qui est utilisée dans mon programme pour s’allumer lorsqu’il n’y a plus de lumière s’illumine.
    Je serais ravis de pouvoir vous montrer mon code afin d’avoir un avis sur la question

    Voir en ligne : Mon petit site sur raspberry

    Répondre

  • Le monde des objets (2) 18 décembre 2017 10:39, par Thierry

    Bonjour

    Votre problème ne traite d’aucun des sujets que nous souhaitons ici, l’Arduino et le modélisme ferroviaire. Je vous conseille donc de faire des recherches ciblées sur les pointeurs de fonction en C++. Vous ne devriez pas avoir de problème à trouver des réponses, les callback sont légion en développement.

    Répondre

  • Le monde des objets (2) 12 janvier 2018 23:36, par trimarco232

    Bonjour,

    si j’ai bien suivi ?
    dans le 1er /// Déclaration de la classe Led
    ligne 45 :
    il y a ’if (aMontageInverse == true)’
    il faut ’if (montageInverse == true)’

    cela semble se confirmer dans le Code complet, ligne 49

    Répondre

    • Le monde des objets (2) 13 janvier 2018 10:34, par Thierry

      C’est vrai, c’est corrigé. Merci de votre attention !

      Répondre

      • Le monde des objets (2) 13 janvier 2018 13:37, par trimarco232

        l’erreur fut sans conséquence
        l’intérêt est des plus mérités : je recommande vivement la lecture de tes articles !

        Répondre

  • Le monde des objets (2) 20 avril 2018 00:00, par BoBillier Eric

    Bonjour merci pour cet article. Juste une petite coquille. Dans le bout de code après le texte :
    Plutôt que d’avoir un constructeur qui va tout mettre à 0, puis un Setup qui va vraiment faire l’initialisation, répartissons mieux les rôles. On peut ajouter à la classe un constructeur avec des arguments :
    Vous avez oublié "Led: :" devant le constructeur.
    Cette erreur est par contre corrigée dans le code complet.
    Cordialement
    Eric

    Répondre

  • Le monde des objets (2) 20 avril 2018 09:24, par Bobillier Eric

    Bonjour. Je m’interroge aussi sur un point de votre exposé.Vous indiquez que le constructeur n’accepte pas de valeur de retour, et vous déclarer Led::Led() sans même de type void devant.
    Cependant dans le chapitre suivant (Le monde des objets(3)) , vous déclarez dans le bout de code après le texte " Cette led particulière ayant deux pins différentes à piloter, il faut en ajouter une à celle déjà présente dans la classe de base, c’est pin2, et l’initialiser dans le constructeur :",le constructeur de la classe ledBicouleur avec un type void devant. D’où ma question : est-ce que les 2 écritures sont valides (avec ou sans type void devant), ou s’agit-il d’une petite coquille ?
    Cordialement
    Eric

    Répondre

  • Le monde des objets (2) 20 avril 2018 14:10, par Thierry

    Non, c’est bien une coquille qui vient d’être corrigée... A ma connaissance, il ne faut jamais spécifier de valeur de retour sur un constructeur, même void !

    Répondre

  • Le monde des objets (2) 17 avril 2020 12:05, par Nans

    Bonjour,

    Tout d’abord merci pour ses explications.
    J’ai bien, il me semble fait tout ce qu’y est expliqué dans cet article cependant quand je veux l’instancier mon objet, j’ai un message du compilateur qui me dit " error :’NameObjet’ does not name a type."

    La déclaration de la class doit-elle ce faire avant l’instanciation dans les sketch ?

    Je précise que ce n’est pas votre exemple mais mon propre objet.

    Cordialement.
    Nans

    Répondre

    • Le monde des objets (2) 17 avril 2020 13:12, par Thierry

      Oui je confirme, le C++ ne peut utiliser que ce qu’il connait déjà, c’est à dire que tout ce qui est utilisé doit être déclaré avant. Par contre il est possible de mettre une ligne ’class toto’ qui indique au compilateur que ça va venir plus tard, mais ça ne fonctionne que pour des déclarations de donnée de ce type là, comme un ’toto MaVariable ;’ ou un argument de fonction de ce type.

      Répondre

  • Le monde des objets (2) 1er avril 2023 18:15, par Benoit92

    Bonjour,
    Je ne suis pas informaticien et je me pose une question (certainement bête !) :
    Pourquoi y a t-il :
    byte pin ;
    bool montageInverse ;
    au début du programme
    et aPin et aMontageInverse dans la suite du programme
    Par exemple : Led(byte aPin, bool aMontageInverse = false) ; // constructeur complet
    Merci.
    Cordialement

    Répondre

    • Le monde des objets (2) 1er avril 2023 18:32

      Bonjour

      pin et aPin sont deux variables différentes. pin est une donnée membre de la classe Led. C’est à dire qu’une Led est définie par sa broche ’pin’ et son état ’etat’ . aPin est un argument (d’où le ’a’) d’une fonction.
      Dans le constructeur, qui est aussi une fonction comme une autre, aPin est passée en argument par la déclaration Led maLed(10) . aPin reçoit alors 10, et le construteur peut en faire ce qu’il veut. Par exemple fixer la broche de la led à ’aPin’, soit 10, comme c’est le cas dans le constructeur décrit dans l’article avec la ligne ’pin = aPin’, mais il aurait pu faire le choix de fixer la broche de la led à 20, avec un ’pin = aPin + 10’ . Pourquoi ? Ben pourquoi pas ! En fait bien souvent, les arguments du constructeur ne consituent pas les données membres du nouvel objet, mais permettent de le construire d’une manière particuliére.
      On aurait pu imaginer avoir une liste de pin broches[5], et donner au constructeur l’indice de la broche à utiliser, et pas la broche elle même :

      int broches[5] = { 10,11,12,13,14 };
      
      Led::Led(int aIndex)
      {
      	pin = broches[aIndex];
      }

      Les arguments d’un constructeur ne présagent forcément pas du contenu de l’instance de classe créée.

      Répondre

  • Le monde des objets (2) 1er avril 2023 19:24, par Benoit92

    Merci,
    Je comprends pas tout, mais je m’accroche !.
    Le format de aPin et aMontageInverse est implicitement défini par :
    pin = aPin ;
    montageInverse = aMontageInverse

    Donc, pin étant déclaré en format byte (8 bits),
    aPin est la variable qui peut potentiellement varier entre 0 et 1024.
    C’est donc aPin qui est appelé dans certaines des fonctions.

    Répondre

Rubrique Programmation

Les derniers articles

Les articles les plus lus