Je programme depuis un certain temps maintenant, mais je suis nouveau dans la programmation Arduino et AVR. La principale question que j'ai à propos de la programmation de ces microcontrôleurs est la suivante: y a-t-il des différences majeures dans la conception de code dans les classes orientées objet par rapport à la programmation en ligne plus traditionnelle que j'ai vue dans de nombreux exemples?
En d'autres termes, dans le monde des contrôleurs Arduino / AVR, y a-t-il des économies avec la mémoire et les performances en utilisant des classes ou vice versa?
Disons par exemple que nous avons une classe:
class SomeClass(){
private:
int x;
int y;
public:
void foo();
void bar();
}
SomeClass thisClass;
thisClass.foo();
thisClass.bar();
Y aurait-il des gains de performances ou de mémoire en concevant le programme d'une manière plus intégrée comme:
int x;
int y;
void foo(){ /*** Do something ***/};
void bar(){ /*** Do more stuff ***/};
J'ai essayé de faire des recherches sur Stack Exchange et Google, mais je n'ai pas trouvé la réponse que je cherchais. La chose la plus proche que j'ai pu trouver était cette question Stack Exchange.
La raison pour laquelle je pose cette question est que j'ai un projet qui doit être aussi léger que possible et je ne sais pas comment je devrais concevoir mon programme dans cet environnement.
Éditer
Merci pour les réponses, cela a fait la lumière sur les choses. Il y a une chose sur laquelle je ne suis pas tout à fait clair.
Supposons que vous ayez une classe que vous concevez qui utilise u8glib comme suit:
class UserInterface{
private:
U8GLIB_ST7920_128X64 Display;
public:
UserInterface();
}
Comment feriez-vous pour utiliser la «mémoire dynamique» comme:
UserInterface::UserInterface(){
UserInterface::Display = U8GLIB_ST7920_128X64(LCD_E_PIN, LCD_RW_PIN, LCD_RS_PIN, U8G_PIN_NONE);
}
la source
UserInterface::UserInterface() : Display(LCD_E_PIN, LCD_RW_PIN, LCD_RS_PIN, U8G_PIN_NONE) { ... }
. Les paramètres nécessaires du constructeur Display doivent être transmis au constructeur UserInterface.La raison pour laquelle vous ne pouvez pas trouver la réponse est que la réponse est à la fois Oui et Non.
Pour les choses de classe de base - définir votre classe avec des méthodes, etc. et en instancier des objets - il y a peu de différence dans le résultat final par rapport à "vanilla" C. Les optimisations du compilateur sont si bonnes maintenant que les performances sont les mêmes. Oui, il peut y avoir une légère augmentation de l'utilisation de la mémoire car vous passez un pointeur supplémentaire à chaque appel de méthode (au lieu que
foo(int x)
vous l'avezfoo(MyClass *this, int x)
), mais c'est si petit qu'il n'est pas perceptible.Les grandes différences surviennent lorsque vous commencez à jouer avec le polymorphisme et d'autres sujets avancés. Lorsque vous commencez à exécuter ces programmes complexes, le compilateur n'est pas toujours incapable de déterminer quelles fonctions sont requises et lesquelles ne le sont pas, et il n'est pas en mesure de supprimer les fonctions inutilisées ( "garbage collection" ). Vous pourriez donc vous retrouver avec un code plus gros.
Cela ne signifie pas un code plus lent, juste des morceaux de code qui traînent et qui ne font jamais rien.
Il est plus important de gérer votre mémoire dynamique mieux que d'habitude. Puisqu'il y a une si petite quantité de mémoire, le tas est très petit et, par conséquent, il se fragmente très facilement. La création et la destruction dynamique des objets (
new myClass
,delete myClassObject
, etc.) est très mauvais. Les objets de classe doivent vraiment être définis statiquement (dans la portée globale est le plus courant) ou temporairement alloués sur la pile (instances locales). Sinon, vous demandez des ennuis - et le premier vous en saurez que des choses étranges se produisent (pas de rapports d'erreur ou d'exceptions, vous voyez ...).la source