Zásobník objektů

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
PetrB
Příspěvky: 141
Registrován: 20 čer 2018, 13:39

Zásobník objektů

Příspěvek od PetrB » 24 čer 2018, 15:20

Ahoj,
Arduino se mi hodně líbí, ale moje pokusy vždy paradoxně končí u programování. Rozběhám si nějaký projekt, který funguje jak po hw, tak i sw stránce, ale pak nastoupí moje programátorská duše a snaží se napsat obslužný program daleko elegantněji. A to je ten problém. Moje dlouhodobě budované návyky většinou moc nefungují.
Mám následující myšlenku:
1) vytvořím základní objekt např. tZaklad, od kterého budu odvozovat nějaké další. Společná bude metoda execute, která se bude v potomcích přepisovat.
2) budu mít "paměťový" objekt tPamet, který se na počátku běhu programu naplní a potom bude podle nějakého klíče připojené objekty spouštět přes metodu execute
3) pro účely testovaní budu mít pamet, která je objektem tPamet a bude obsahovat prvek1 a prvek2 (oba jsou potomky tZaklad)

v Zaklad.h

Kód: Vybrat vše

#ifndef Zaklad_h
#define Zaklad_h

#include "Arduino.h"
 class tZaklad
  {
   private:
    int cislo;
   public:
    tZaklad(int  vCislo); //inicializace
    
    virtual void execute(); //vykonej něco
  }
#endif
v Zaklad.cpp

Kód: Vybrat vše

#include "Arduino.h"
 tZaklad::tZaklad(int vCislo) {
  cislo=vCislo;
  }
  
  tZaklad::execute() {
   cislo=cislo+1;
   serial.println(cislo);
  }
v Pamet.h

Kód: Vybrat vše

#ifndef Pamet_h
#define Pamet_h

#include "Arduino.h"
#include "Zaklad.h"

 class tPamet
  {
   private:
    tZaklad *obsah[20];  //muze obsahovat max 20 objektu
    int pocet;  //kolik jich obsahuje
   public:
    tPamet(); //inicializace
    
    void registruj(tZaklad &vst); //přidej si prvek
    void execute(); //vykonej něco
  }
#endif
v Pamet.cpp

Kód: Vybrat vše

#include "Arduino.h"

 tPamet::tPamet() {
  pocet=0;
 }
 
 tPamet::registruj(tZaklad &vst) {
  obsah[pocet]=vst;  //Jednoduše bez kontroly přetečení, ta teď není podstatná
  pocet++;
 } 
 
 tPamet::execute() {
  for (int i=0;i<pocet;i++) {
   obsah[i]->execute();
  }
 }
a v hlavní knihovně Test.h bych chtěl mít něco jako toto:

Kód: Vybrat vše

#include "Pamet.h"
#include "Zaklad.h"

 class tPrvek1 : tZaklad {
  virtual void execute() {
    cislo=cislo+2;
   serial.println(cislo);
  }  
 };
 
  class tPrvek2 : tZaklad {
  virtual void execute() {
    cislo=cislo+3;
   serial.println(cislo);
  }  
 }

//tohle neumím vytvořit
 tZaklad prvek0(0);
 tPrvek1 prvek(1);
 tPrvek2 prvek(2);
 
 tPamet pamet();
 
 void setup() {
 Serial.begin(9600);
 //A tady si to připojím do paměti
 pamet->registruj(&prvek0);
 pamet->registruj(&prvek1);
 pamet->registruj(&prvek2);
 }
 
 void loop() {
  pamet->execute();
  delay(1000);
 }
Můžete se mi na to někdo podívat a připadně to opravit? Moje obecná myšlenka je taková, že udělám např. základní objekt pro obecné čidlo, podle jeho povahy si ho v budoucnu dodefinuji, připojím do paměťového objektu a ten si je bude sám obstarávat. Stejně jako např. objekt webového serveru, do kterého si budu registrovat jednotlivé stránky.
Základem je to, že nepočítám s nějakým dodatečným dynamickým vytvářením a rušením objektů a pod. Také počty připojených objektů můžou být max v desítkách kusů.

Díky

Petr

martinius96
Příspěvky: 585
Registrován: 01 srp 2017, 19:29
Bydliště: Poprad
Kontaktovat uživatele:

Re: Zásobník objektů

Příspěvek od martinius96 » 27 čer 2018, 15:33

Myslím, že s týmto ti tu nikto neporadí. Všetci na fóre programujeme skôr procedurálnym štýlom a nie objektovým.
Nevidel som tu na fóre ešte post s objektovou paradigmou :-)

PetrB
Příspěvky: 141
Registrován: 20 čer 2018, 13:39

Re: Zásobník objektů

Příspěvek od PetrB » 27 čer 2018, 17:05

No, já to zkoušel i na arduino.cc a tam mi taky moc neporadili. Asi si moc vymýšlím. Problém je v tom, že jak vidím x podobných činností, tak se snažím objektovat a tady se peru se syntaxí. ;-)
Zkusil jsem to a nevyšlo. Budu hledat jinou cestu (pole rekordů na metody možná), ale bude mi to hodně proti srsti :lol:

Každopádně díky za reakci.

Uživatelský avatar
gilhad
Příspěvky: 851
Registrován: 07 bře 2018, 11:22

Re: Zásobník objektů

Příspěvek od gilhad » 28 čer 2018, 15:15

Ja vlastni objekty na Arduinu celkem bezne pouzivam (ostatne co jineho je Wire, Serial, ... ze) a nemam zadne (neocekavane) problemy.

Ale neni mi jasne, co ti nejde, jake chybove hlasky to dela, jak jsi to zkusil opravit, co to delalo pototm a tak ...

Obecne pokud umis rozdelit problem na jednotlive objekty a nejak si je mezi sebou zorganizovat, tak je to zajiste chvalihodna myslenka.

Ale cidla jsou nejruznejsiho druhu, vraci nejruznejsi udaje, nektere reaguji okamzite, jinym to nejakou dobu trva (takze je vhodne mit moznost je volat neblokujicim zpusobem a nez si nameri sve veliciny, tak delat neco uzitecneho a pak si jen vzit vysledky, jindy zase clovek bez tech vysledku nema jak pokracovat dal, tak potrebuje na ne pockat ... ty vysledky muzou byt jednoduche (on/off pro tlacitko), slozitejsi (0..1024 pro analog), s pameti (bylo stisknuto od posledniho dotazu?), struktury (datum+cas), vice rozmerne (treba gyroskop a akcelerometr vraci asi tak 6 a vic hodnot), navzajem nesouviselici (teplomer+vlhkomer), strukturovane (pokud je cidlo treba dalsi arduino a shrnuje komplexne vnitrni stav robota od celkoveho OK/problem/nefunkcni az po odbery jednotlivych motoru, jejich teploty, ujetou drahu a tak podobne).

Takze sam uvaz, jak obecne to chces, co to ma umet a co uz je pro tebe zbytecne, to za tebe asi nikdo nevymysli, protoze udelat to uplne univerzalne znamena stvorit molocha, ke kteremu bude navod na tri svazky a nikdo ho nebude pro jeho slozitost pouzivat.

Pak napis nejaky priklad pouziti (treba s tlacitkem, potenciometrem a rotacnim enkoderem) a nejakym rozumnym vystupem a kdyz ti to nebude chodit a vyzkousis obecne zname postupy (napriklad precteni si vystupu z kompilatoru a doplneni vsech zapomenutych stredniku a jinych preklepu) a budes mit nejaky konkretni problem, tak se zeptej, je sance ze nekdo bude vedet. Ale obecne vysvetlit, jak se pracuje se vsemi cidly, jak se tvori objektove programy, jak objekty mohou interagovat ... to muze byt klidne nametem nekolika semestru na VS, ne kratkeho prispevku na foru.

PetrB
Příspěvky: 141
Registrován: 20 čer 2018, 13:39

Re: Zásobník objektů

Příspěvek od PetrB » 29 čer 2018, 13:59

Ono jde o to, že to neumím pořádně napsat. Syntaxe C++ je pro mne trochu zakletá a ani z návodů jsem toho moc nevyčetl.

Jde mi o to udělat např. následující:
základní web server, který přijme od uživatele požadavek a obejde s ním své "podřízené". Některému se ten požadavek zalíbí, tak ho vykoná a vrátí serveru, že už se tím nemusí zabývat.
Potom bych si při programování podle potřeb aplikace vyráběl ty stránky jako potomky základního objektu a o zbytek bych se nemusel starat (klasika objektové programování).

To samé čidla/senzory. Měly by základní metody (něco jako init, StartujCteni, Cteni,Ukladani) a opět by je majitel na začátku oběhnul, aby se inicializovali. Pak jim řekne, aby začaly číst, pak by jim řekl ať načtou a na konec ukládají,...

Majitel by měl na začátku něco jako AddClient, kam by se přidal nově vytvořený podřízený po patřičném nastavení parametrů.

Ta čidla a senzory zatím nemám promyšlené, teď se rvu s tou kostrou pro web a nedokážu to napsat.

Nechci nic složitého, jenom s obsluhou pár prvků (max 10-20?), ale chci si ušetřit práci při budoucím psaní a některé věci unifikovat.

PetrB
Příspěvky: 141
Registrován: 20 čer 2018, 13:39

Re: Zásobník objektů

Příspěvek od PetrB » 29 čer 2018, 14:10

P.S. - nejde mi o to, aby to za mne někdo napsal. V podstatě mi tolik nejde o výsledek, jako o cestu...

Očekávám spíše, že mi někdo poradí se syntaxí:
1) Jak napsat objekt (to už vím, ale v kontextu s tím ostatním)
2) jak dědit objekt a přepisovat metody
3) jak vytvořený objekt přiřadit do nějakého pole, abych mohl zavolat prvek toho pole, jeho metodu a vykonala se ta správná (patrně zděděná a přepsaná).

Stačí jednoduché (schválně to nepíšu jako kód, protože si nejsem jistý zápisem):
objekt TZaklad s virtuální metodou Vykonej
jeho potomek TPotomek1 s přepsanou metodou Vykonej, která udělá něco jiného
jiný potomek TPotomek2 opět s vlastní podobou metody Vykonej

Potom budu mít pole, kterému budu přiřazovat objekt TZaklad a jeho potomky.
Vytvořím Zaklad, což bude objekt typu TZaklad
vytvořím potomky Potomek1 (od TPotomek1) a Potomek2 (od TPotomek2)
Všechny tři potom postupně přiřadím do pole pod indexy 0..2

A na konec projdu pole (proměnná i) a vykonám metody Vykonej pro jednotlivé prvky pole.
Očekávám, že se provede metoda z TZaklad pro i=0, TPotomek1 pro i=1 a na konec TPotomek2 pro i=2.

Takže pokud toto uvidím a budu mít jistotu, že je to funkční, tak si podle toho vytvořím svůj plánovaný pokus.

Snad už jsem se popsal lépe.

Díky

Uživatelský avatar
gilhad
Příspěvky: 851
Registrován: 07 bře 2018, 11:22

Re: Zásobník objektů

Příspěvek od gilhad » 29 čer 2018, 15:41

Tak by to melo fungovat - udelej to a uvidis. Pro zacatek klidne Vykonej muze zablikat diodou podle typu objektu, nebo vypsat neco na Serial.

PetrB
Příspěvky: 141
Registrován: 20 čer 2018, 13:39

Re: Zásobník objektů

Příspěvek od PetrB » 29 čer 2018, 16:18

Nepochopil ;-(

Algoritmizaci mám zvládnutou (programuji přes 30 let, ale ne C++), mám i program, který funguje, ale neumím napsat správně ty objekty přes které to chci zjednodušit. Neumím tu syntaxi a ani jsem ji nenašel (na jednoduché objekty ano, ale ne dědění a ukládání ukazatelů na objekty).

Prostě, jak napsat TZaklad, jak jeho potomky aby měli vlastní Vykonej. A hlavně, jak je vytvořit a přiřadit do toho pole? To mi nejde.

V Delphi bych napsal:
Type
TZaklad = Class
Constructor Create;
procedure Vykonej;virtual;
End;
TPotomek1 = Class(TZaklad)
procedure Vykonej;override;
End;

TPole = array [0..20] Of TZaklad;
TMajitel = Class
pamet : TPole;
pPocet : Integer;

Constructor Create;
Procedure Pripoj(VKoho : TZaklad);
Procedure Vykonej;
End;

Constructor TMajitel.Create;
Begin
//něco
pPocet:=-1;
End;

Procedure TMajitel.Pripoj(VKoho : TZaklad);
Begin
Inc(pPocet);
pamet[pPocet]:=VKoho;
End;

Procedure TMajitel.Vykonej;
Var
I : integer;
Begin
For I=0 to pPocet do
pamet.Vykonej;
End;

Var
Majitel : TMajitel;
Begin
Majitel:=TMajitel.Create;
Majitel.Pripoj(TZaklad.Create);
Majitel.Pripoj(TPotomek1.Create);
.....
Majitel.Vykonej;
End;

A tohle bych potřeboval přepsat pro Arduino a nejde mi to.
Pb

Uživatelský avatar
gilhad
Příspěvky: 851
Registrován: 07 bře 2018, 11:22

Re: Zásobník objektů

Příspěvek od gilhad » 30 čer 2018, 23:27

Tak jsem si tvuj kod zkopiroval a byl plny syntaktickych chyb (zapomenute stredniky, zapomenute #include, zapomenute navratove typy funkci, konstruktory a tak podobne), kdyz jsem narychlo docistil, za co mi prekladac nadaval, vyslo mi tohle - urcite to jde docesat lip, ale funguje to)

Kód: Vybrat vše

Pamet.cpp:
#include "Arduino.h"
#include "Pamet.h"

 tPamet::tPamet() {
  pocet=0;
 }
 
 void tPamet::registruj(tZaklad *vst) {
  obsah[pocet]=vst;  //Jednoduše bez kontroly přetečení, ta teď není podstatná
  pocet++;
 } 
 
 void tPamet::execute() {
  for (int i=0;i<pocet;i++) {
   obsah[i]->execute();
  }
 }





Pamet.h:
#ifndef Pamet_h
#define Pamet_h

#include "Arduino.h"
#include "Zaklad.h"

 class tPamet
  {
   private:
    tZaklad *obsah[20];  //muze obsahovat max 20 objektu
    int pocet;  //kolik jich obsahuje
   public:
    tPamet(); //inicializace
    
    void registruj(tZaklad *vst); //přidej si prvek
    void execute(); //vykonej něco
  };
#endif






Test.ino:
#include "Pamet.h"
#include "Zaklad.h"

 class tPrvek1 : public tZaklad {
  public:
     tPrvek1(int vCislo):tZaklad(vCislo){};
  virtual void execute() {
    cislo=cislo+2;
   Serial.println(cislo);
  }  
 };
 
  class tPrvek2 : public tZaklad {
  public:
     tPrvek2(int vCislo):tZaklad(vCislo){};
  virtual void execute() {
    cislo=cislo+3;
   Serial.println(cislo);
  }  
 };

//tohle neumím vytvořit
 tZaklad prvek0= tZaklad(0);
 tPrvek1 prvek1= tPrvek1(1);
 tPrvek2 prvek2= tPrvek2(2);
 
 tPamet pamet= tPamet();
 
 void setup() {
 Serial.begin(9600);
 //A tady si to připojím do paměti
 pamet.registruj(&prvek0);
 pamet.registruj(&prvek1);
 pamet.registruj(&prvek2);
 }
 
 void loop() {
  pamet.execute();
  Serial.println("-----");
  delay(1000);
 }





Zaklad.cpp:
#include "Arduino.h"
#include "Zaklad.h"
tZaklad::tZaklad(int vCislo) {
  cislo=vCislo;
  }
  
  void tZaklad::execute() {
   cislo=cislo+1;
   Serial.println(cislo);
  }





Zaklad.h:
#ifndef Zaklad_h
#define Zaklad_h

#include "Arduino.h"
 class tZaklad
  {
   protected:
    int cislo;
   public:
    tZaklad(int  vCislo); //inicializace
    
    virtual void execute(); //vykonej něco
  };
#endif

1
3
5
-----
2
5
8
-----
3
7
11
-----
4
9
14
-----
5
11
17
-----
6
13
20
-----
7
15
23
-----



PetrB
Příspěvky: 141
Registrován: 20 čer 2018, 13:39

Re: Zásobník objektů

Příspěvek od PetrB » 30 čer 2018, 23:48

Díky, po tom jsem toužil! ;-)

Vyzkouším to.

Promiň za tu syntax. Psal jsem to z hlavy (potřeboval jsem jenom ukázat základní princip) a moc to zatím v tomto jazyce neumím.

Pb

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 1 host