C++ call back

pouCZ

C++ call back
« kdy: 19. 12. 2023, 13:03:23 »
Ahoj,
chci se zeptat zda níže uvedený přístup k vytvoření zpětného volání z rodiče na potomka je dobré.
Jde mi o toto: chci mít v rodiči pole (vektor)  struktr ve kterých budou registrované funkce pro volání (včetně podmínek kdy se daná funkce má zavolat).
Potomek si potom vytvoří vlastní libovolnou funkci a podmínku za které se tato funkce zavola - toto si zaregistruje (podmínka může být např. periodicky  12s). Rodič potom ve funkci process() zjistí zda podmínka platí a zavolá příslušnou funkci.



Děkuji



Kód: [Vybrat]
#include <iostream>
class BASE_CLASS {
public:
    BASE_CLASS() : callbackFce(nullptr) {}
    template <typename T>
    void registerCallBack(void (T::*callback)()) {
        callbackFce = dynamic_cast<void (BASE_CLASS::*)()>(callback);
    }

    void process() {
        if (callbackFce != nullptr) {
            (this->*callbackFce)();
        }
    }
private:
    void (BASE_CLASS::*callbackFce)();
};

class FOOO : public BASE_CLASS {
public:
    FOOO() : BASE_CLASS() {
        registerCallBack(&FOOO::callbackFunction);
    }
protected:
    void callbackFunction() {
        std::cout << "Hello" <<std::endl;
    }
};

int main() {
    FOOO test;
    test.process();
    return 0;
}


alex6bbc

  • *****
  • 1 670
    • Zobrazit profil
    • E-mail
Re:C++ call back
« Odpověď #1 kdy: 19. 12. 2023, 13:12:51 »
a neni to zbytecne slozite?

rodicovska trida muze mit jen virtualni metodu process.

odvozena trida potomek reimplementuje metodu process a uvnitr se muze spustit cokoliv.

pouCZ

Re:C++ call back
« Odpověď #2 kdy: 19. 12. 2023, 13:19:50 »
Díky za odpověď.
To by samozřejmě šlo, jenže to by pak každý potomek musel implementovat skoro to samé.
Co se týče např. času tak uložit si poslední čas a pak jestli uběhlo už X sekund.... Příjde mi to pak že opakuji zbytečný kód.
Navíc počítám že těch podmínek by pak mohlo být víc.

alex6bbc

  • *****
  • 1 670
    • Zobrazit profil
    • E-mail
Re:C++ call back
« Odpověď #3 kdy: 19. 12. 2023, 13:25:55 »
Díky za odpověď.
To by samozřejmě šlo, jenže to by pak každý potomek musel implementovat skoro to samé.
Co se týče např. času tak uložit si poslední čas a pak jestli uběhlo už X sekund.... Příjde mi to pak že opakuji zbytečný kód.
Navíc počítám že těch podmínek by pak mohlo být víc.

tak muzete zaklad/boilerplate implementovat v rodicovi v metode process a rodic muze mit i prazdnou virtualni funkci,
ktera bud ma prazdny vnitrek, nebo je deklarovana treba void specialni_funkce() = 0;

a rodic bude mit v process()
{
...hafo kodu....
specialni_funkce();
}

a potomci uz budou mit jenom neco jineho ve specialni_funkce.

v tride to mas mit zapouzdrene, callback ma smysl, ale tady bych nerekl, ze ma.

alex6bbc

  • *****
  • 1 670
    • Zobrazit profil
    • E-mail
Re:C++ call back
« Odpověď #4 kdy: 19. 12. 2023, 13:27:02 »
jinak v c++ se koukni na std::function a lambda.


pouCZ

Re:C++ call back
« Odpověď #5 kdy: 19. 12. 2023, 13:33:36 »
jenže jak bys např. udělal že jeden potomek chce zavolat funkci1() - každou sekundu,  funkci2() co 10s a funkci3() co 15s atd ( např. teď píšu potomka co chci aby jednou za 10minut zkontroloval připojená čidla, každé 2minuty reportoval teplotu a co 1s hlídal překročení teploty).
Jenže jiní potomci vůbec časové funkce nepotřebují - nač je mít tedy implementovane v předkovi (sice s prázdným tělem).....A to bych tam měl mít v tom předkovi pro každý čas fnkci? Nebo mít v předkovi pevný počet funkcí na čas a jen proměnnýma vybírat kdy se jaká spouští??

Nevím možná je to tak správně - proto se ptám.

alex6bbc

  • *****
  • 1 670
    • Zobrazit profil
    • E-mail
Re:C++ call back
« Odpověď #6 kdy: 19. 12. 2023, 13:49:21 »
jenže jak bys např. udělal že jeden potomek chce zavolat funkci1() - každou sekundu,  funkci2() co 10s a funkci3() co 15s atd ( např. teď píšu potomka co chci aby jednou za 10minut zkontroloval připojená čidla, každé 2minuty reportoval teplotu a co 1s hlídal překročení teploty).
Jenže jiní potomci vůbec časové funkce nepotřebují - nač je mít tedy implementovane v předkovi (sice s prázdným tělem).....A to bych tam měl mít v tom předkovi pro každý čas fnkci? Nebo mít v předkovi pevný počet funkcí na čas a jen proměnnýma vybírat kdy se jaká spouští??

Nevím možná je to tak správně - proto se ptám.

rodicovska trida muze treba obsahovat pole (lambda) funkci, vektor pointeru na funkce, vektor std::function nebo nemusis ani pouzit dedeni, ale muzes pouzit template.

od zakladni tridy muzes mit odvozeno vice potomku, jeden muze mit implementaci pro casovace, dalsi potomek nemusi.
spolecnou maji jen metodu process().

 

mhi

  • *****
  • 500
    • Zobrazit profil
Re:C++ call back
« Odpověď #7 kdy: 19. 12. 2023, 14:07:01 »
jenže jak bys např. udělal že jeden potomek chce zavolat funkci1() - každou sekundu,  funkci2() co 10s a funkci3() co 15s atd ( např. teď píšu potomka co chci aby jednou za 10minut zkontroloval připojená čidla, každé 2minuty reportoval teplotu a co 1s hlídal překročení teploty).
Jenže jiní potomci vůbec časové funkce nepotřebují - nač je mít tedy implementovane v předkovi (sice s prázdným tělem).....A to bych tam měl mít v tom předkovi pro každý čas fnkci? Nebo mít v předkovi pevný počet funkcí na čas a jen proměnnýma vybírat kdy se jaká spouští??

Moje odpoved neni C++, ale jestli to je embedded vec, tak tohle si rika primo o vyuziti sluzeb RTOS.

V automotive se pouziva OSEK, ktery na toto ma vse potrebne.

(ovsem ne vsude, jedna automobilka ma implementovano v roce 2022 tohle v ECU motoru pomoci nekolika fci obsahujici hejno volani dalsich fci a je to nejak rozdelene na "volej casto" "volej mene casto" "volej jeste mene casteji" ...)


Jestli jsou ty C++ tridy tak odlisne, ze vznikaji subsety virtualnich metod, zavani to trosku spatnym navrhem, ale to jen odhaduji. Chtelo by to asi vice detailu.

alex6bbc

  • *****
  • 1 670
    • Zobrazit profil
    • E-mail
Re:C++ call back
« Odpověď #8 kdy: 19. 12. 2023, 14:21:38 »
jenže jak bys např. udělal že jeden potomek chce zavolat funkci1() - každou sekundu,  funkci2() co 10s a funkci3() co 15s atd ( např. teď píšu potomka co chci aby jednou za 10minut zkontroloval připojená čidla, každé 2minuty reportoval teplotu a co 1s hlídal překročení teploty).
Jenže jiní potomci vůbec časové funkce nepotřebují - nač je mít tedy implementovane v předkovi (sice s prázdným tělem).....A to bych tam měl mít v tom předkovi pro každý čas fnkci? Nebo mít v předkovi pevný počet funkcí na čas a jen proměnnýma vybírat kdy se jaká spouští??

Moje odpoved neni C++, ale jestli to je embedded vec, tak tohle si rika primo o vyuziti sluzeb RTOS.

V automotive se pouziva OSEK, ktery na toto ma vse potrebne.

(ovsem ne vsude, jedna automobilka ma implementovano v roce 2022 tohle v ECU motoru pomoci nekolika fci obsahujici hejno volani dalsich fci a je to nejak rozdelene na "volej casto" "volej mene casto" "volej jeste mene casteji" ...)


Jestli jsou ty C++ tridy tak odlisne, ze vznikaji subsety virtualnich metod, zavani to trosku spatnym navrhem, ale to jen odhaduji. Chtelo by to asi vice detailu.

tohle jde i v ramci c++ resit tunou ruznych reseni, takze tezko autorovi presne poradit.

Re:C++ call back
« Odpověď #9 kdy: 19. 12. 2023, 17:50:07 »
Proč vlastně chceš použít dědičnost? Přijde mi, že sem se moc nehodí...
Jinak to zní zhruba jako ScheduledExecutorService v Javě ( https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html ), v C++ se bohužel moc nevyznám, ale možná existuje taky něco podobnýho

alex6bbc

  • *****
  • 1 670
    • Zobrazit profil
    • E-mail
Re:C++ call back
« Odpověď #10 kdy: 19. 12. 2023, 19:16:17 »

pouCZ

Re:C++ call back
« Odpověď #11 kdy: 20. 12. 2023, 08:43:21 »
Jedná se o domácí bastl kód - žádné auto-motive nebo nic produkčního.
Tvořím na raspberry pico ovládání žaluzií, ovládání podlahovky a čtení teplot atd.
Cílem bylo vytvořit něco jako možnost potomků si zapnout periodické volání nějakých metod - nic víc.


Pokud to tedy chápu dobře, tak na zmíněném přístupu nic špatně není, ale je moc složitý. Je to tak?

Děkuji za std::function to jsem neznal a dalo by se také použit.


modnar

Re:C++ call back
« Odpověď #12 kdy: 20. 12. 2023, 09:44:35 »
Jedná se o domácí bastl kód - žádné auto-motive nebo nic produkčního.
Tvořím na raspberry pico ovládání žaluzií, ovládání podlahovky a čtení teplot atd.
Cílem bylo vytvořit něco jako možnost potomků si zapnout periodické volání nějakých metod - nic víc.

Snad si psal, ze to bude v Rustu ne? Takze zmena na C++, ktere je pro tebe opet moc zlozite? Nechapu.

alex6bbc

  • *****
  • 1 670
    • Zobrazit profil
    • E-mail
Re:C++ call back
« Odpověď #13 kdy: 20. 12. 2023, 11:26:15 »
Jedná se o domácí bastl kód - žádné auto-motive nebo nic produkčního.
Tvořím na raspberry pico ovládání žaluzií, ovládání podlahovky a čtení teplot atd.
Cílem bylo vytvořit něco jako možnost potomků si zapnout periodické volání nějakých metod - nic víc.


Pokud to tedy chápu dobře, tak na zmíněném přístupu nic špatně není, ale je moc složitý. Je to tak?

Děkuji za std::function to jsem neznal a dalo by se také použit.

v c/c++ muzes napsat co chces :-)
ale doporucuji to psat co nejjednoduseji/nejpochopitelneji a dokumentovat.

a v dnesni dobe je dobre se drzet metod moderniho c++.

pouCZ

Re:C++ call back
« Odpověď #14 kdy: 20. 12. 2023, 11:41:01 »
Jedná se o domácí bastl kód - žádné auto-motive nebo nic produkčního.
Tvořím na raspberry pico ovládání žaluzií, ovládání podlahovky a čtení teplot atd.
Cílem bylo vytvořit něco jako možnost potomků si zapnout periodické volání nějakých metod - nic víc.

Snad si psal, ze to bude v Rustu ne? Takze zmena na C++, ktere je pro tebe opet moc zlozite? Nechapu.


Možná jsem před Vánoci trochu chorý na mysli ale o Rustu jsem se snad nezmínil....