Re: Jak správně rozdělit C++ projekt

Miroslav Mraz mrazik na volny.cz
Pondělí Srpen 23 21:12:46 CEST 2021


V C++ se spíš používá zapouzdření všeho co jde do tříd. Moderní 
překladač umí kód dobře optimalizovat, takže výsledek je někdy i kratší 
než čisté C. Na globální proměnné a nějaké makra můžete klidně 
zapomenout. Struktura by byla asi nějak takto (c++14):

////////////////// hlavicky ////////////////////////
#ifndef AB_H
#define AB_H
// misto define se spis pouziva constexpr kvuli lepsi typove kontrole
constexpr int GLOBAL = 666;
constexpr int FACT (const int n) {  // faktorial se vyhodnoti uz pri 
prekladu
   return n <= 1 ? n : n * FACT (n - 1);
}
// oddelit co je mozne a dat fo samostatnych trid
// jednotlive tridy dat do samostatnych souboru (.h, .cpp)
class A {
   static constexpr int PIN = 5;  // byvale define
   int a,b;                       // byvale globalni promenne
   public:
     // lze volat konstruktory i pro int, ale budou nastaveny v setup()
     explicit A () : a(1), b(2) {};
     void setup () { // jednoduche funkce mohou byt definovany v .h, pak 
jsou inline
       a = FACT (PIN);  // vyhodnoceno jako a = 120
       b = GLOBAL;   // ...
     }
     void loop ();   // v .h muze byt jen deklarace, vlastni kod pak v .cpp
};
class B {
   // tady muzou mit promenne stejna jmena jako v A, jsou to ale jina 
pametova mista
   static constexpr int PIN = 10;
   int a,b;
   protected: // puvodni globalni funkce tykajici se jen teto casti lze 
deklarovat jako chranene metody
     void function ();
   public:
     explicit B () {};
     void setup () {
       a = GLOBAL;
       b = PIN;
     }
     void loop ();
};
#endif // AB_H
///////////////////// zapouzdreni /////////////////////////
#ifndef SUPER_H
#define SUPER_H
#include "ab.h"

class Super {
   A a;
   B b;
   public:
     explicit Super() : a(),b() {};
     void setup () {
       a.setup();
       b.setup();
     }
     void loop () {
       a.loop();
       b.loop();
     }
};
#endif // SUPER_H
///////////////////// main.cpp ///////////////////
#include "super.h"

static Super super;

void setup () {
   super.setup();
}
void loop () {
   super.loop();
}
/** Definice metod, ma byt v samostatnych souborech pro A, B **/
void A::loop () {
   printf ("A::a=%d, b=%d\n", a, b);
   a += 1; // ...
}
void B::loop () {
   printf ("B::a=%d, b=%d\n", a, b);
   function();
   b -= 5;
}
void B::function () {
   printf("call protected %s\n", __FUNCTION__);
   b += 4;
}
Samozřejmě si to každý může udělat po svém, možností je dost a Arduino 
není v používání zapouzdření důsledné, takže lze čekat problémy. Nicméně 
chci tím říct, že přístup k řešení problému je v každém jazyce jiný a je 
dobré si to předem rozmyslet a složitější strukturu programu přizpůsobit 
paradigmatu jazyka už od začátku. Dodatečné úpravy pak bývají dost pracné.

Mrazík

Dne 23. 08. 21 v 16:48 Petr Labaj napsal(a):
> Asi jde o to, o co jde.
> Jestli to má být přehledné a pochopitelné pro Vás, nebo i pro nějaké 
> cizí lidi, případně to má sloužit třeba pro zápočet na škole.
> 
> Řekl bych, že je dobré mít pohromadě věci, které patří k sobě.
> Za sebe si myslím, že dobrým zvykem je, že "include" by neměl obsahovat 
> výkonný kód, ale jenom makra a deklarace.
> A skládání výkonného kódu pak nechat na projektu/make/linkeru.
> Ale je-li to jen pro Vás, a vyhovuje Vám to, tak klidně skládat i *.c.
> Podle klíčových slov "setup" a "loop" to bude nějaká Arduinovina, takže 
> to zřejmě nebude kdovíjak rozsáhlý projekt.
> 
> Kdybych to dělal já, tak bych věci, které patří k sobě, dal do jednoho 
> souboru. Případně i s globálními proměnnými, které k tomu patří.
> Do jednoho *.h, které bych pak do všech modulů includoval, bych pak dal 
> deklarace všech funkcí ze všech modulů.
> A také deklarace proměnných (s příznakem "extern") , ale jen těch, které 
> se používají ve více modulech.
> Takže globálky, použité jen jedním modulem, by zůstaly jen v něm.
> Což funguje jako aspoň triviální kontrola a přehled, co se používá různě 
> křížově.
> 
> Anebo třeba úplně jinak. ;-)
> 
> PL
> 


Další informace o konferenci Hw-list