Stránka 1 z 1
Jak napsat odkaz na funkci třídy
Napsal: 25 čer 2020, 16:19
od PetrB
Ahoj,
zase hledám, jak něco napsat. Tentokrát potřebuji laborovat s odkazem na funkci třídy.
Co chci napsat: mám nějakou obecnou třídu, která má funkci execute a ta si umí zavolat nějakou funkci (s předem jasnými parametry), která ji je předaná v rámci parametrů.
Umím to napsat jako odkaz na statickou metodu:
Kód: Vybrat vše
typedef bool(*provedNeco)(int vParametr);
class tTrida {
tTrida() {}
void execute(provedNeco vCo) {
if (vCo(5)) {
Serial.println(F("O.K."));
}
}
}
bool Test(int vParametr) {
return vParametr==3;
}
void setup() {
pObjekt=new tTrida();
pObjekt->execute(*Test);
}
Ale pokud by metoda Test měla být součástí třídy, tak mi to napsat nejde.
Někde jsem našel přibližně toto:
Kód: Vybrat vše
class TVolanaTrida; //forward deklarace
typedef bool(TVolanaTrida::*provedNeco)(int vParametr);
class tTrida {
tTrida() {}
void execute(provedNeco vCo) {
if (vCo(5)) {
Serial.println(F("O.K."));
}
}
}
class TVolanaTrida{
tVolanaTrida(){}
bool Test(int vParametr) {
return vParametr==3;
}
void provedSebe(tTrida vKudy) {
//Tohle neumím napsat. Asi něco jako
vKudy.execute(*Test);
}
}
void setup() {
pVolana=new tVolanaTrida();
pObjekt=new tTrida();
pVolana->provedSebe(pObjekt);
}
Otázka je tedy celkem jednoduchá. Jak mám napsat že třída předá jako parametr do nějaké funkce odkaz na svoji metodu? Ta funkce potom tuto metodu vyvolá s nějakými parametry. Jde mi de facto o jakési "call back volání". V jednom objektu mám generální metodu tvořící tabulku v HTML. Jako parametr je jí předán nějaký obecný objekt (třeba seznam teploměrů) a ten jí na zavolání bude přes určitou funkci předávat parametry pro tuto tabulku.
Vím, že si dost vymýšlím, ale jsem zvyklý programovat v jiných jazycích a zde jsou mi zatím nějaké věci dost utajené.
Díky
Pb
Re: Jak napsat odkaz na funkci třídy
Napsal: 02 črc 2020, 15:53
od KiLLA
..jestli to dobře chápu, pomůže ti zjištění, že pointery na funkce musej bejt statický, a můžeš si předávat dynamicky pointer na staickej pointer, pokud je to potřeba..

Re: Jak napsat odkaz na funkci třídy
Napsal: 02 črc 2020, 17:26
od PetrB
Můžeš mi hodit příklad?
V Delphi to napsat umím:
Kód: Vybrat vše
Type
TFunkce = Function (vParam : Integer) : string of object;
TPracuje = Class
constructor Create; //tento konstruktor je prázdný, nebudu to rozepisovat
procedure Execute(VCo : TFunkce;vParam : Integer);
End;
TCeka = Class
pHodnota : Integer;
constructor Create(vParam : Integer);
Function MneVolej(vParam : Integer) : String;
End;
procedure TPracuje.Execute(VCo : TFunkce;vParam : Integer);
Begin
Writeln(VCo(vParam)); //Vyvolej metodu VCo, předej jí parametr vParam a výsledek vytiskni
End;
constructor TCeka.create(vParam : Integer);
Begin
pHodnota:=vParam;
End;
Function TCeka.MneVolej(vParam : Integer) : String;
Begin
Result:=IntToStr(vParam+pHodnota); //Převeď parametr na text
End;
Var
pracuje : TPracuje;
ceka : TCeka;
ceka1 : TCeka;
Begin
pracuje:=TPracuje.Create; //Vytvoř objekty
ceka:=TCeka.Create(0);
ceka1:=TCeka.Create(1);
...
pracuje.execute(ceka.MneVolej,1); //Volej funkci prvního objektu
pracuje.execute(ceka1.MneVolej,2);//Volej funkci druhého objektu
...
End;
Uměl by si mi to přepsat pro arduino?
Jde o to, že objekt TPracuje v rámci metody Execute volá metody jiného objektu. No a ten TCeka mu ji poskytuje.
V tuto chvíli nemám žádný konkrétní příklad, spíše mne zajímá, jak se to v Arduinu napíše (pokud to jde).
Díky
Re: Jak napsat odkaz na funkci třídy
Napsal: 03 črc 2020, 00:24
od KiLLA
trochu sem to pochopil špatně, koukám
v delphi sem nikdy nic nepsal
ale z posledních řádků mezi begin a end je patrný co to má cca dělat..
u cpp podobnou funkčnost umožňuje friend class, kdy lze použít i private members ze zpřátelený třídy
Kód: Vybrat vše
class TCeka {
friend class TPracuje;
};
horší to je se spouštěním timhle způsobem, zjednodušil bych to..
tohle de dosadit i jako vlastnost třídy..
Kód: Vybrat vše
typedef void (* functionPointer) ();
functionPointer pracuje;
pracuje = ceka;
pracuje();
ale možná by bylo jednodušší volat funkci přímo

Re: Jak napsat odkaz na funkci třídy
Napsal: 03 črc 2020, 08:18
od PetrB
Díky, výhledově se s tím pokusím nějak popasovat.
Jde mi o to, že mám nějaký objekt, který se má obecně starat o web server a obsluhovat jednotlivé stránky, které má v sobě registrované. Tam je to jednoduché, každá stránka má svoji metodu "execute", která ji vygeneruje a web server ji volá.
Pak mám ovšem obecný "senzor", který si nějak načítá svoje hodnoty a ty potom umí "poslat" na stránku. Senzor by těch metod pro posílání mohl mít více (např. podle charakteru stránky a pod.) a jde o to, že by si ten senzor zaregistroval svoji metodu pro konkrétní stránku a ta by ji potom v rámci svého "execute" vykonala. Dopředu tedy nevím, jaká to bude metoda, ale znám její parametry. V maximalistickém případě by mohla mít stránka z těch metod dokonce pole a cyklicky je volat.
Ale to byl jenom takový nápad.
Každopádně díky za typ.
Pb
Re: Jak napsat odkaz na funkci třídy
Napsal: 03 črc 2020, 10:03
od KiLLA
opravená provní část kódu
Kód: Vybrat vše
typedef bool(*provedNeco)(int vParametr);
class tTrida {
public:
tTrida() {}
int16_t execute(provedNeco vCo) {
if (vCo(5) == true) { // testnem to
Serial.println(F("O.K."));
}
else {
Serial.println(F("Error."));
}
}
}; // <-- chyběl středníček
bool Test(int vParametr) {
Serial.println(F("Test run."));
return vParametr == 5;
}
void setup() {
Serial.begin(115200); // bez toho to nevim nevim
//pObjekt = new tTrida(); // error :-D
tTrida pObjekt; // radši takhle
pObjekt.execute(*Test); // a takto
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println(F("Nemám rád češtinu v kódu."));
delay(1000);
}
Re: Jak napsat odkaz na funkci třídy
Napsal: 03 črc 2020, 12:46
od KiLLA
..když sem tu druhou část přepsal, aby to odpovídalo, házelo mi to pořád chyby.. mrknu na to o víkendu, ale problém je v tom, že pointer na member funkci je jinej, než na fci bez třídy.. i když to mám napsaný (nejspíš) dobře, arduino ide to odmítá zkompilovat..

Re: Jak napsat odkaz na funkci třídy
Napsal: 03 črc 2020, 13:38
od KiLLA
https://stackoverflow.com/questions/860 ... s-function
arduino ide odmítá zkompilovat i toto..
https://www.codeguru.com/cpp/cpp/articl ... nction.htm
https://isocpp.org/wiki/faq/pointers-to-members
trochu víc do detailů..
na web z 8266 bych použil něco klasickýho, tohle je zbytečně komplikovaný -> blbě by se to udržovalo a když s tim pak pohneš, třeba bys to i přepisoval, protože to kuli x,y,z nepude.. výstupy ze senzoru nacpat do struct, tu jako parametr k funkcím..
může si s sebou nýst i pointer na odpovídající funkci..
Kód: Vybrat vše
typedef void (* functionPointer) ();
struct Result
{
uint32_t value = 0; //
functionPointer function;
};
Result result; // global
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
// Result result; // local
result.function = hehe;
result.function(); //<------
test(&result);
delay(1000);
}
void hehe() {
Serial.println(F("lololololo"));
}
void test(Result* res) {
Serial.print(F("result value: ")); Serial.println(res->value);
res->value++;
}