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

Bibliothèques C++ Discussion :

Accès aux attributs d'une classe


Sujet :

Bibliothèques C++

  1. #1
    Membre habitué
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 293
    Points : 145
    Points
    145
    Par défaut Accès aux attributs d'une classe
    Bonjour,
    j'ai créé un objet Relais dans une petite bibliothèque pour gérer le fonctionnement de relais. Ceux-ci fonctionnent correctement. J'ai ajouté une méthode pour lire l'état de mes relais (ON ou OFF). Mais là, ils sont toujours à OFF.
    Je dois faire une erreur de concept dans le fonctionnement de ma Classe. Si quelqu'un pouvait m'éclairer?
    Relais.h
    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
     
    /**********************************************************
    **************Bibliotèque Relais***************************
    *******************************Mormic mai 2021*****/
    #ifndef RELAIS_H_INCLUDED
    #define RELAIS_H_INCLUDED
     
    #include "Arduino.h"
     
    class Relais{
    protected:
        int rPin;
        char rMode;
        unsigned int rTime;
    public:
        bool rEtat;
        Relais();
        Relais(int pin, char m, unsigned int t=0);
        void begin();
        void actionOn();
        void actionOf();
        bool relEtat();
    };
    #endif //  RELAIS_H_INCLUDED
    Relais.cpp
    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
    48
    49
    50
     
    /**********************************************************
    **************Bibliotèque Relais***************************
    *******************************Mormic mai 2021*****/
     
    #include "Relais.h"
    Relais::Relais(){}
     
    Relais::Relais(int pin, char m, unsigned int t){
        rPin = pin;
        rMode = m;
        rTime = t;
     
    }
    void Relais::begin(){
        pinMode(rPin,OUTPUT);
     }
    void Relais::actionOn(){         //mode interrupteur
        unsigned long x, y;
        if(rMode == 'I'){
            digitalWrite(rPin,HIGH);
            rEtat = true;
        }
        else if(rMode =='T'){       //mode temporisation
            y = rTime * 1000;
            digitalWrite(rPin,HIGH);
            x = millis();
            rEtat = true;
            while(millis()-x <= y){}
            digitalWrite(rPin,LOW);
            rEtat = false;
        }
        else if(rMode =='P'){       //mode poussoir
            y = rTime;
            digitalWrite(rPin,HIGH);
            x = millis();
            while(millis()-x <=y){}
            digitalWrite(rPin,LOW);
            rEtat = !rEtat;
        }
    }
    void Relais::actionOf(){
        if(rMode == 'I' || rMode =='T'){
            digitalWrite(rPin, LOW);
            rEtat = false;
        }
    }
    bool Relais::relEtat(){
        return rEtat;
    }
    Prog
    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
     
    Relais rel1(25, 'I');        //mode 'I'=Inter 'P'=Poussoir temps en millis 'T'=Tempo en secondes
    Relais rel2(26, 'P', 500);   //Instance de l'objet Relais (pin, mode, temps commutation)
    Relais rel3(27, 'T', 4);
     
      rel1.begin();
      rel2.begin();
      rel3.begin();
     
    //***************************Analyse message bluetooth*************************************
    void analyseBT(String msg){
      String x = msg.substring(0,3);
      if(x=="env"){envoiEnviron();}
      else if(x=="tem"){envoiTemp();}
      else if(x=="rel"){comRelais(msg);}   //forme de la commande: relxon / relxof
      else if(x=="con"){configTemp(msg);}  //commande: conftempx
      else if(x=="eta"){envoiEtatRel();}   //commande: etat
    }
    //******************************Commandes des relais**************************************
    void comRelais(String msg){     //forme de la commande: relxon ou relxof
      Relais rel;
      switch(msg.charAt(3)){
          case '1': rel = rel1; break;   
          case '2': rel = rel2; break;
          case '3': rel = rel3; break;
        } 
      if(msg.charAt(5)=='n') rel.actionOn();      //'n' -> on   'f' -> off
      else if(msg.charAt(5)=='f') rel.actionOf();
    }
    //***********************Envoi l'état des relais*********************************
    void envoiEtatRel(){
     /* Relais rel[3] = {rel1, rel2, rel3};
      for(int i=0; i<3; i++){
        if(rel[i].relEtat() == true) SerialBT.println("Relais " + String(i+1) + " : ON");
        else SerialBT.println("Relais " + String(i+1) + " : OFF");
      }
      */
      if(rel1.relEtat() == true) SerialBT.println("Relais 1: ON");
        else SerialBT.println("Relais 1: OFF");
      if(rel2.relEtat() == true) SerialBT.println("Relais 2: ON");
        else SerialBT.println("Relais 2: OFF");
      if(rel3.relEtat() == true) SerialBT.println("Relais 3: ON");
        else SerialBT.println("Relais 3: OFF");
     
    }
    Merci d'avance
    Michel

  2. #2
    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 : 60
    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 642
    Points
    7 642
    Par défaut
    Bonjour,


    Dans Prog ligne 21, tu crées un 4ième relai. Ligne 23/24/25 tu y recopies un des relais, et ligne 27/28 tu utilises ce 4ième relai. Donc à aucun moment tu n'utilises un de 3 relais et ils ne changent pas d'état!
    Il te faut désigner et surtout pas prendre un copie du relai que tu veux utiliser. Pour cela tu as, soit les pointeurs soit les références. Ici utiliser un pointeur est plus immédiat à écrire qu'une référence, mais les deux sont possibles.
    Et tu pourras en profiter pour supprimer le constructeur par défaut d'un Relais, ça n'a pas vraiment de sens et t'empêchera la tentation de réécrire la ligne 21.

  3. #3
    Membre habitué
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 293
    Points : 145
    Points
    145
    Par défaut
    Merci pour l'intérêt que tu as porté à ma question.
    J'ai parfaitement compris mon problème de 4ème Relais.
    Par contre, n'étant pas expert en la matière je n'ai pas compris le terme "Désigner"; quant aux pointeurs, je ne vois pas non plus comment les utiliser.

    En attendant une réponse , j'ai trouvé une solution empirique:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Relais rel1(25, 'I');        //mode 'I'=Inter 'P'=Poussoir temps en millis 'T'=Tempo en secondes
    Relais rel2(26, 'P', 500);   //Instance de l'objet Relais (pin, mode, temps commutation)
    Relais rel3(27, 'T', 4);
    Relais rel[3] = {rel1, rel2, rel3};
    char relTemp;                //relais affecté à la température
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      for(int i=0;i<3;i++){
        rel[i].begin();
      }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //***********************Envoi l'état des relais*********************************
    void envoiEtatRel(){
      for(int i=0; i<3; i++){
        if(rel[i].relEtat()) SerialBT.println("Relais " + String(i+1) + " : ON");
        else SerialBT.println("Relais " + String(i+1) + " : OFF");
      }
    }
    //******************************Commandes des relais**************************************
    void comRelais(String msg){     //forme de la commande: relxon ou relxof
      int z = msg.charAt(3)-49;     //code ascii 0=48  -1 car rel1 c'est rel[0]
      if(msg.charAt(5)=='n') rel[z].actionOn();      //'n' -> on   'f' -> off
      else if(msg.charAt(5)=='f') rel[z].actionOf();
    }
    Ce n'est surement pas du beau C++ mais cela fonctionne.
    Par contre si tu pouvais me mettre sur la voie pour utiliser les pointeurs, cela me ferait certainement évoluer.

    Merci encore
    Michel

  4. #4
    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 mormic Voir le message
    quant aux pointeurs
    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
    void comRelais(String msg){     //forme de la commande: relxon ou relxof
      Relais* rel;
     
      switch(msg.charAt(3)){
          case '1': rel = &rel1; break;   
          case '2': rel = &rel2; break;
          case '3': rel = &rel3; break;
          default: rel = NULL;
      }
     
      if (rel != NULL) {
          if(msg.charAt(5)=='n') rel->actionOn();      //'n' -> on   'f' -> off
          else if(msg.charAt(5)=='f') rel->actionOf();
      }
    }
    Après, au lieu d'affecter NULL tu peux peut-être faire 1 return. Mais dans 1 switch, je ne sais pas si cela fonctionne (sûrement que oui)


    Citation Envoyé par mormic Voir le message
    Relais rel[3] = {rel1, rel2, rel3};
    Le problème avec ton tableau, c'est que ce sont des copies. Tu peux aussi utiliser 1 std::vector.
    Mais en cas de redimensionnement, tu ne vas pas déplacer tes relais, mais les dupliquer (et détruire l'original)
    Et donc tu ne peux pas prendre l'adresse d'1 relais pour l'utiliser.

    L'autre problème c'est qu'avec 1 tableau, il appelle forcément le constructeur par défaut (on ne peux pas appeler 1 autre, mais à vérifier). Pour palier cela, tu peux :
    • faire 1 "lazy contructeur" (qui met tout à zéro) + 1 méthode init avec les bons paramètres t_relais array_relais[3]; array_relais[0].init(25, 'I'); array_relais[1].init(26, 'P', 500);. Il te faut également 1 mode pour dire "non initialisé".
    • mettre des pointeurs dans ton tableau t_relais* array_relais[3];. Mais cela fait trop d'allocations/ désallocations pour pas grand chose.

  5. #5
    Membre habitué
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 293
    Points : 145
    Points
    145
    Par défaut
    Bonjour et merci pour toutes ces explications.
    J'ai compris l'accès aux membres de ma Classe Relais par le "->" mais je pense n'être qu'au début de la compréhension des arcanes des pointers avec les Classes.
    Mon programme fonctionne maintenant; voici ce que cela donne:

    Relais.h
    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
    /**********************************************************
    **************Bibliotèque Relais***************************
    *******************************Michel MORICE mai 2021*****/
    #ifndef RELAIS_H_INCLUDED
    #define RELAIS_H_INCLUDED
     
    #include "Arduino.h"
     
    class Relais{
    protected:
        int rPin;
        char rMode;
        unsigned int rTime;
        bool rEtat;
    public:
        Relais(int pin, char m, unsigned int t=0);
        void begin();
        void actionOn();
        void actionOf();
        bool relEtat();
    };
    #endif //  RELAIS_H_INCLUDED
    Relais.cpp
    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
    /**********************************************************
    **************Bibliotèque Relais***************************
    *******************************Michel MORICE mai 2021*****/
     
    #include "Relais.h"
     
    Relais::Relais(int pin, char m, unsigned int t){
        rPin = pin;
        rMode = m;
        rTime = t;
    }
    void Relais::begin(){
        pinMode(rPin,OUTPUT);
     }
    void Relais::actionOn(){         //mode interrupteur
        unsigned long x, y;
        if(rMode == 'I'){
            digitalWrite(rPin,HIGH);
            rEtat = true;
        }
        else if(rMode =='T'){       //mode temporisation
            y = rTime * 1000;
            digitalWrite(rPin,HIGH);
            x = millis();
            rEtat = true;
            while(millis()-x <= y){}
            digitalWrite(rPin,LOW);
            rEtat = false;
        }
        else if(rMode =='P'){       //mode poussoir
            y = rTime;
            digitalWrite(rPin,HIGH);
            x = millis();
            while(millis()-x <=y){}
            digitalWrite(rPin,LOW);
            rEtat = !rEtat;
        }
    }
    void Relais::actionOf(){
        if(rMode == 'I' || rMode =='T'){
            digitalWrite(rPin, LOW);
            rEtat = false;
        }
    }
    bool Relais::relEtat(){
        return rEtat;
    }
    Procédures:
    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
    48
    49
    50
    51
    52
    53
    54
    55
    Relais rel1(25, 'I');        //mode 'I'=Inter 'P'=Poussoir temps en millis 'T'=Tempo en secondes
    Relais rel2(26, 'P', 500);   //Instance de l'objet Relais (pin, mode, temps commutation)
    Relais rel3(27, 'T', 4);
    char relTemp;                //relais affecté à la température
     
      rel1.begin();
      rel2.begin();
      rel3.begin();
     
    //***********************Envoi l'état des relais*********************************
    void envoiEtatRel(){
      Relais *rel;
      for(int i=1;i<4;i++){
        switch(i){
          case 1 : rel=&rel1; break;
          case 2 : rel=&rel2; break;
          case 3 : rel=&rel3; break;
        }
        if(rel->relEtat()) SerialBT.println("Relais " + String(i) + ": ON");
        else SerialBT.println("Relais " + String(i+1) + ": OFF");
      }
    }
    //******************************Commandes des relais**************************************
    void comRelais(String msg){     //forme de la commande: relxon ou relxof
      Relais *rel;
      ok=true;
      switch( msg.charAt(3)){
        case '1': rel = &rel1; break;
        case '2': rel = &rel2; break;
        case '3': rel = &rel3; break;
        default : 
          SerialBT.println(F("Ce relais n'existe pas"));
          ok=false;
          break;
      }
      if(msg.charAt(5)=='n' && ok) rel->actionOn();      //'n' -> on   'f' -> off
      else if(msg.charAt(5)=='f' && ok) rel->actionOf();
      ok=true;
    }
    //***************************Analyse températures******************************************
    void analyseTemp(){
      Relais *rel;
      int z = relTemp-48;
      switch (z){
        case 1: rel=&rel1; break;
        case 2: rel=&rel2; break;
        case 3: rel=&rel3; break;
      }
      if(temperature < tBasse && !rel->relEtat()){
        rel->actionOn();
      }
      else if(temperature >= tHaute && rel->relEtat()){
        rel->actionOf();
      }
    }
    Si vous avez des améliorations a y apporter, je suis preneur.
    Merci encore.
    Michel

  6. #6
    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 mormic Voir le message
    J'ai compris l'accès aux membres de ma Classe Relais par le "->" mais je pense n'être qu'au début de la compréhension des arcanes des pointers avec les Classes.
    Il n'y a rien à comprendre : XXX* pour faire 1 type pointeur pointant vers 1 variable de type XXX, &XXX pour prendre l'adresse d'1 variable, (*XXX), (*XXX).yyy, XXX->yyy pour déférencer.
    Cela ouvre la porte à l'allocation dynamique : malloc/ free en C et new/ delete/ delete[] en C++.

    Non ce qui demande le + à savoir c'est :
    • l'expérience. Concevoir 1 programme, en faisant attention aux variables partagées (nombre de propriétaires, lecture seulement, ...) afin d'éviter les fuites mémoires et les plantages ("dangling references" en anglais ou pointeur non [ré]initialisé essentiellement)
    • le C++ moderne, depuis C++11/ C++14/ C++17/ ..., qui met en avant les pointeurs intelligents ("smart pointers" en anglais) et écarte les pointeurs nus ("raw pointers" en anglais)


    Après, il y a des subtilités : les tableaux C
    • le nom du tableau est 1 pointeur sur le premier élément
    • le passage des paramètres qui dégrade le passage tableau en pointeur (seulement la première dimension)
    • obligation de se trimbaler sa taille - faire 1 structure/ classe
    • les types complets/ incomplets - les pointeurs contrairement aux tableaux n'ont pas besoin d'avoir la définition du type
    • le sizeof du pointeur qui fait toujours 4 (32 bits) ou 8 (64 bits) - les débutants se font tous avoir

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

Discussions similaires

  1. [Débutant] Accès aux attributs d'une classe
    Par stracoma dans le forum VB.NET
    Réponses: 9
    Dernier message: 17/05/2015, 22h10
  2. Accès aux attributs d'une autre classe
    Par alexmam15 dans le forum Débuter
    Réponses: 5
    Dernier message: 25/02/2011, 09h26
  3. [PHP 5.3] Empêcher l'accés aux attributs d'une classe ?
    Par tintin72 dans le forum Langage
    Réponses: 1
    Dernier message: 20/08/2010, 14h58
  4. Accès aux attributs propres à une classe fille
    Par jamilya dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 24/12/2008, 15h06
  5. [TOMCAT] JSP problème d'accès aux méthodes d'une classes
    Par gunnm dans le forum Tomcat et TomEE
    Réponses: 3
    Dernier message: 22/05/2004, 14h02

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