Volání metody ukazatelem – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Volání metody ukazatelem – C / C++ – Fórum – Programujte.comVolání metody ukazatelem – C / C++ – Fórum – Programujte.com

 

19. 9. 2013   #1
-
0
-

Ahoj,

v metodě třídy A potřebuji zavolat metodu jiné třídy B aniž bych znal jméno této metody v době psaní kódu třídy A.

Zkoušel jsem ve třídě B voláním funkce MethodAdress("JmenoMetody") naplnit strukturu TMethod a tu pak předat jako parametr v konstruktoru třídy A. Struktura TMethod obsahuje ukazatele na objekt a na jeho metodu. To jsem našel v nápovědě, jen nevím, co s tím dál. Asi jsem ve slepé uličce. 

Používám C++ Builder 2010

hu

Nahlásit jako SPAM
IP: 195.178.67.–
KIIV
~ Moderátor
+43
God of flame
19. 9. 2013   #2
-
0
-

muzes zkusit boost::bind  nebo uz je mozna i v ramci standardu nejakej bind

Nahlásit jako SPAM
IP: 94.112.35.–
Program vždy dělá to co naprogramujete, ne to co chcete...
19. 9. 2013   #3
-
0
-

Zkus to víc rozepsat

hu

Nahlásit jako SPAM
IP: 195.178.67.–
KIIV
~ Moderátor
+43
God of flame
19. 9. 2013   #4
-
0
-

no treba todle mi zda se funguje:   

class test {
  public:
    bool test1(int x, double y) { return true; }
    bool test2(int x, double y) { return true; }
    bool test3(int x, double y) { return true; }
};

class druhy {
  public:
    bool (test::* callback)(int,double);
    bool call(test & x) { (x.*callback)(1,2.3); }
};


int main()
{
  test a;
  druhy b;

  b.callback = &test::test1;

  b.call(a);

  return 0;
}

takze jestli ses schopen dostat tu adresu metody nejakym zpusobem ...

ale i tak mi to zni jako blbej navrh

Nahlásit jako SPAM
IP: 94.112.35.–
Program vždy dělá to co naprogramujete, ne to co chcete...
19. 9. 2013   #5
-
0
-

V každé aplikaci, kde se to použije, bych musel mít stejně pojmenovanou třídu, ukazatel na ni a její metodu. Kromě toho bych vždy musel měnit zdrojový kód aby byl vložen správný hlavičkový soubor. 

Cílem bylo vytvořit rozhraní tak, aby se do kódu příjmu dat již nemuselo zasahovat.

V podstatě se mi jedná o předání dat přijatých od periferie hlavnímu vláknu. Jedna z možností je použít Copy Data Structure a posílat zprávu. Zde by stačilo předat handle, což by nebylo problém. Druhá možnost je použít sdílený kus paměti. Hlavní vlákno by muselo v pravidelných intervalech kontrolovat nějaký příznak, zda jsou k dispozici nová data. Třetí možnost je zavolat metodu hlavního vlákna, v tomto případě pointerem. Mechanismus synchronizace existuje ( Synchronize(&Metoda) ). Třetí možnost se mi zdála nejlepší, ale neumím ji udělat

hu

Nahlásit jako SPAM
IP: 188.95.60.–
KIIV
~ Moderátor
+43
God of flame
19. 9. 2013   #6
-
0
-

to zni spis na to ze budes potrebovat adapter...

Nahlásit jako SPAM
IP: 94.112.35.–
Program vždy dělá to co naprogramujete, ne to co chcete...
19. 9. 2013   #7
-
0
-

???

hu

Nahlásit jako SPAM
IP: 188.95.60.–
KIIV
~ Moderátor
+43
God of flame
19. 9. 2013   #8
-
0
-
Nahlásit jako SPAM
IP: 94.112.35.–
Program vždy dělá to co naprogramujete, ne to co chcete...
19. 9. 2013   #9
-
0
-

Mohla by se jmenovat pokaždé stejně. Template ... v živodě jsem žádnou nenapsal a ani nemám tušení, jak se to dělá.   .

hu

Nahlásit jako SPAM
IP: 188.95.60.–
KIIV
~ Moderátor
+43
God of flame
19. 9. 2013   #10
-
0
-

dalsi moznost je pokud mas ruzny tridy, tak mohou dedit stejny interface (virtualni metody, virtualni trida) .. pak staci mit popis base class (ten interface v nejakem include souboru) a volat to vzdy tim, co je k tomu urcene...

template by vypadal treba nejak takto:

template <class T> void pridat_neco(T & trida, string co) { trida.metoda1(co); }

Nahlásit jako SPAM
IP: 94.112.35.–
Program vždy dělá to co naprogramujete, ne to co chcete...
19. 9. 2013   #11
-
0
-

Asi se naučím, že hlavní wokno se bude jmenovat vždy Fmain a tím pádem se třída bude jmenovat vždy TFmain. A když bude mít vždy stejnojmennou metodu, bude po problému :(

hu

Nahlásit jako SPAM
IP: 188.95.60.–
20. 9. 2013   #12
-
0
-

#10 KIIV
Aspoň se ty šablony naučím. Zkusím to.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
20. 9. 2013   #13
-
0
-

Nakonec mne napadlo jednoduché řešení (že mne nenapadlo hned?):

v souboru vlakno.hpp pouze deklarace metody

void PredejData();

a implementace až v cpp souboru aplikace, ve které se vlákno použije:

#include "vlakno.hpp"

void vlakno::PredejData()
{
  //kod metody
}

a teď do mne, že je to prasárna.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
vitamin+8
Grafoman
20. 9. 2013   #14
-
0
-

#13 hlucheucho
Čo chceš presne vytvoriť?

Nahlásit jako SPAM
IP: 195.28.77.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
20. 9. 2013   #15
-
0
-

#14 vitamin
Vlákno komunikace s periferií tak aby šlo použít ve více aplikacích. Řeším jak předat data z vlákna komunikace s periferií do hlavního vlákna, kde běží GUI poskládané z VCL. Hlavní vlákno je potomek třídy TForm, tvoří ho C++ Builder automaticky při grafickém návrhu GUI. Vlákno komunikace je potomek třídy TThread. Problém vzniká v univerzálnosti vlákna komunikace, kde nevím, jaká přesně bude třída (vím jen že je to potomek TForm) a její metoda (co bude aplikace s daty dělat), kterou budu volat při předávání dat. Malé usnadnění může být, že se metoda bude jmenovat vždy stejně. Stejně tak bych mohl přistoupit na "štábní kulturu" kde by se hlavní okno a tím i třída hlavního vlákna jmenovali stejně v každé aplikaci. Obě vlákna jsou vytvářena dynamicky, jsou k dispozici ukazatele.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
vitamin+8
Grafoman
20. 9. 2013   #16
-
0
-

#15 hlucheucho
Podla mna bude asi nejlepsie pouzit ten interface co ti radil kiiv. Ak by si chcel definovat komunikaciu nezavysle na triedach TForm a TThread, mozes pouzit nasledovne templaty:

template <class T>
void send_data(T&, /*data*/);	//funkcia nema ziadne telo

template<>
void send_data(TForm& obj, /*data*/){
	obj.metoda(/*data*/)
}

template<>
void send_data(TFormXYZ& obj, /*data*/){
	obj.ina_metoda(/*data*/)
}
Nahlásit jako SPAM
IP: 195.28.77.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
20. 9. 2013   #17
-
0
-

je to marný, ty šablony asi nikdy nepochopím   . Nemáš nějaký odkaz kde by to bylo vysvětleno pro pitomce?

hu

Nahlásit jako SPAM
IP: 195.178.67.–
vitamin+8
Grafoman
20. 9. 2013   #18
-
0
-

#17 hlucheucho
Comu nechapes na templatoch?

Nahlásit jako SPAM
IP: 195.28.77.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
20. 9. 2013   #19
-
0
-

Jak ty zápisy číst, jak to vytvořit

hu

Nahlásit jako SPAM
IP: 195.178.67.–
vitamin+8
Grafoman
20. 9. 2013   #20
-
+1
-
Zajímavé

Ak das pred triedu/strukturu alebo funkciu (v pripade c++11 aj using) klucove slovo template a za nim v hranatych zatvorkach definujes template parametre (typy alebo integer). 

template <class T, int I>
struct B{
	T[I] t;	
	
	I size()const{return I;}
	
	typedef T type;

};

template <typename T, class U, struct X>	//typename, class a struct su v tomto pripade ekvivalentne
T fnc(U& u, const X& x){
	//...
}

Syntax je rovnaka aku pri normalnych triedach a funkciach.

Potom tu je specializacia templatov. Triedy mozu mat ciastocnu specializaciu, funkcie len uplnu specializaciu:

//ciastocna specializacia:

template <class T>
struct B<T, 23>{
	//telo moze byt uplne ine ako v povodnej triede!! :
	//...
};

//uplna specializacia:

template <>
struct B<int, 24>{
	//telo moze byt uplne ine ako v povodnej triede!! :
	//...
};

//funkcia moze mat len uplnu specializaciu:

template <>	//typename, class a struct su v tomto pripade ekvivalentne
int fnc<int, float, char>(float& u, const char& x){
	//...
}
//alebo skratena verzia:
template <>
int fnc(float& u, const char& x){
	//...
}

Pouzitie templatov:


B<bool, 34>	b;	//pouzies template triedu B 

int i = fnc<int, float, double>(7, 3.14f, 6.28lf);	
//alebo:
long l = fnc<long>(7, 3.14f, 6.28lf);	//dva template parametre sa vydedukuju z parametrov funkcie, prvy parameter sa pouziva ako navratova hodnota a ten sa nemoze vydedukovat

Templaty sa prekladaju az v momente ked ich pouzies a template parametre sa nahradia za konkretne typy/cisla. 

Samozrejme su tu este zlozitejsie veci ako template template parametre, vnorene templaty a pristupovanie k prvkom dedeneho templatu z ineho templatu

Edit:

V c++11 je to rozsirene este aj o variadic templaty:

void fnc(){/*nic*/}

template <class A, class As...>
void fnc(A a, As... args){
	cout << sizeof...(As) << ": " << a;
	fnc(args...);	//rekruzivne volani templatu, ale nie je to rekruzia
}

a v c++14 (c++1y) sa zrejme pridaju este zjednodusene koncepty ktore to este spravja zlozitejsie, hlavne pravidla overloadingu template parametrov na zaklade konceptov :)

takze je dobre sa zacat zaoberat templatmi aj ked ich syntax je dost divoka... 

Nahlásit jako SPAM
IP: 195.28.77.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 15 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý