Bonjour
Le programme précédent avec 4 leds fonctionne très bien tel quel, mais si on veut le faire évoluer les choses vont se compliquer. Voici deux exemples entre autres qui vont poser problème :
Premier casSupposons que je veuille faire quelques traitements sur une led, par exemple la deuxième, comme on le recommande je vais utiliser une variable intermédiaire pour économiser des indiçages superflus, donc écrire quelque chose comme cela :
Led led=ledTab[1];
On a fait une copie sans trop s'en rendre compte, c'est "foutu" les leds du tableau ne seront pas modifiées si on modifie la copie.
Deuxième casLe programme précédent ayant l'air de fonctionner (et il fonctionne), en tant que "débutant" je m'enhardi en essayant de faire de l'héritage, de façon classique et comme dans les articles sur les objets de Locoduino, j'essaye de faire une LedBicouleur héritant de Led. Cela donne quelque chose comme cela :
class Led {
protected: int mPin;
public: Led(int inPin) : mPin(inPin) {}
public: void display() { printf("%d ",mPin); }
};
class LedBicouleur : public Led {
private: int mPin2; // deuxieme pin
public: LedBicouleur(int inPin,int inPin2) : Led(inPin),mPin2(inPin2) {}
public: void display() { printf("%d-%d ",mPin,mPin2); }
};
Led ledTab[] = {
Led(10),
LedBicouleur(8,9),
Led(3),
Led(2)
};
int main(int argc, char **argv) {
for (int i = 0; i < 4; i++) {
ledTab[i].display();
}
}
Comme je tiens à pouvoir facilement exécuter les programmes, c'est écrit en C++ standard (pas spécialement pour l'Arduino), donc il me faut adapter les entrées/sorties et avoir une fonction main à la place du setup(), en plus j'ai changé les uint8_t en int (pour la lisibilité). J'ai du passer aussi la variable mPin de Led de private à protected (pour l'héritage).
La classe LedBicouleur hérite de la classe Led, elle rajoute une variable pour la deuxième pin, un constructeur comme il faut et une nouvelle méthode display() pour afficher les deux pins.
Dans le tableau de leds j'ai changé une Led en LedBicouleur. On exécute, cela donne :
10 8 3 2
Grosse déception, les deux pins de la LedBicouleur ne sont pas affichées
En tant qu'informaticien le tableau de leds me pose un problème une LedBicouleur prend plus de place qu'une Led (un entier de plus), le compilateur n'a que deux possibilités, soit il tronque la LedBicouleur à la taille de Led, soit il alloue de la place pour 4 LedBicouleur. Après vérifications (sizeof) il me semble que le compilateur tronque.
BilanLa BONNE solution pour éviter ces problèmes (et d'autres) c'est d'utiliser systématiquement des pointeurs sur les objets quand on veut les manipuler. Voila ce que cela donne :
class Led {
protected: int mPin; float x;
public: Led(int inPin) : mPin(inPin) {}
public: virtual void display() { printf("%d ",mPin); }
};
class LedBicouleur : public Led {
private: int mPin2; double x,y,z; // deuxieme pin
public: LedBicouleur(int inPin,int inPin2) : Led(inPin),mPin2(inPin2) {}
public: virtual void display() { printf("%d-%d ",mPin,mPin2); }
};
Led* ledTab[] = {
new Led(10),
new LedBicouleur(8,9),
new Led(3),
new Led(2)
};
int main(int argc, char **argv) {
for (int i = 0; i < 4; i++) {
ledTab[i]->display();
}
}
Cela affiche :
10 8-9 3 2
Les deux objets n'ont pas été modifiés (à part l'ajout de "virtual" à la méthode display() (nécessaires pour le polymorphisme)
Le tableau de Leds à été transformé en tableau de pointeurs de Leds, et le programme de test (main()) à été modifié en conséquence.
Amicalement
Pierre