[c++] wskaźniki na składowe klasy bez typu klasy

0

Witam,

czy jest mozliwosc wywolania funkcji bedacej skladową klasy tylko za pomocą wskaźnika na obiekt tej klasy i wskaznika funkcji ale w ten sposob, ze nie wiadomo jakiej klasy jest obiekt?

czyli mam wskaznik typu void* na obiekt jakiejs klasy
i mam wskaznik na funkcje skladowa o znanych parametrach

z gory dzieki za odpowiedz

0

Z teog co wiem to nie, ale wskaźnik do pokazywania na klasę podstawową nadaje się też do pokazywania na klasę pochodną. Może to pomoże :P

0
sprzedamsanki napisał(a)

Z teog co wiem to nie, ale wskaźnik do pokazywania na klasę podstawową nadaje się też do pokazywania na klasę pochodną. Może to pomoże :P

Ta niestety tak to teraz mam rozwiazane, ale wyglada to tak karkolomnie, ze chcialem uproscic sprawe.

0

czesciowo sie da, acz to niecalkiem trywialna zabawa. trzeba polaczyc obydwa pomysly: wskaznik na metode + polimorfizm.

mozna np. tak:

struct Definicje()
{
    virtual string funkcja1(string param) = 0;
    virtual string funkcja2(string param) = 0;
    virtual string funkcja3(string param) = 0;

    typedef string (Definicje::* Funkcja)(string param);
    //typ Definicje::Funkcja jest wskaznikiem na metode z klasy Definicje, metode ktora bierze string i zwraca string
};

class Zestaw1 : public Definicje
{
public:
    virtual string funkcja1(string param){return param+"A";}
    virtual string funkcja2(string param){return param+"B";}
    virtual string funkcja3(string param){return param+"C";}
};

class Zestaw2 : public Definicje
{
public:
    virtual string funkcja1(string param){return param+"X";}
    virtual string funkcja2(string param){return param+"Y";}
    virtual string funkcja3(string param){return param+"Z";}
};

w ten sposob bedziesz mogl np:

int main()
{
    Definicje* ob;
    Definicje::Funkcja metoda;

    ob = new Zestaw1();
    metoda = &Definicje::funkcja3;
    cout << (ob ->* metoda)("...") << endl;  //wywolanie Zestaw1::funkcja3

    metoda = &Definicje::funkcja1;
    cout << (ob ->* metoda)("...") << endl;  //wywolanie Zestaw1::funkcja1

    delete ob;
    ob = new Zestaw2();
    cout << (ob ->* metoda)("...") << endl;  //wywolanie Zestaw2::funkcja1
}

w ten sposob:

  • kod wywolujacy metode nie wie jaki jest dokladnie typ obiektu.. ale wiadomo ze dziedziczy on po Definitions
  • kod wywolujacy metode nie wie ktora to z trzech funkcji.. ale wiadomo ze jedna z nich. i wiadomo jaki jest typ ten funkcji
  • funkcje ktore chcesz moc 'wybierac' musza miec ten sam typ (tutaj: string(string)) - inaczej nie bedziesz w stanie przekazac funkcji przez zmienna [pomijam template'y]
  • funkcje ktore chcesz wywolywac na konkretnych klasach musza byc przez nie znane i zamplementowane. stad przychodzi wymog wspolnej bazy, oraz wymog aby wszystkie mozliwe funkcje byly w niej dokladnie wyliczone. pojawia sie tu problem, jak zrobic jesli Zestaw1 ma miec funckje funckja1, a Zestaw2 nie ma jej miec.

wskaznik-na-metode jest zwyklym typem danych, tak wiec mozna robic takie rzeczy jak skladowanie ich w tablicy itp:

...
    Definicje::Funkcja metoda[5];
    metoda[0] = &Definicje::funkcja3;
    metoda[1] = &Definicje::funkcja2;
    metoda[2] = &Definicje::funkcja1;
    metoda[3] = &Definicje::funkcja2;
    metoda[4] = &Definicje::funkcja3;

    ob = new Zestaw1();
    for(int i=0;i<5;++i)
        cout << (ob ->* metoda[i])("...") << endl;  //wywolanie Zestaw1::funkcjaX wg listy
...

i tak dalej..

0

ok, spojrzcie na to: http://msdn2.microsoft.com/en-us/library/ee2k0a7d(VS.71).aspx

teraz pytanie jak napisac wlasna implementacje bo jak rozumiem _events to rozszerzenie microsoftu

0

to jest c++/cli. w c++ najlepsze co uzyskasz to mneiwiecej to co napisalem. jesli do tego dolaczysz template'y, to uzyskasz takie slicznosci jak boost::bind, boost::lambda::bind, boost::memfn itp. jesli nie chcesz zmieniac jezyka,polecalbym Ci juz teraz zaczac sciagac i kompilowac boosta, a w miedzy czasie zaznajomic sie ze skladnia pointer-to-member. potemwziac boost'a i jego dodatki wspomagajce w obroty. a jak chcesz zmieniac jezyk to najpierw poznaj C++ potem C#, a dopiero potem wez sie za C++/CLI, inaczej moze byc ciezko zrozumiec niektore rzeczy..

0
quetzalcoatl napisał(a)

to jest c++/cli. w c++ najlepsze co uzyskasz to mneiwiecej to co napisalem. jesli do tego dolaczysz template'y, to uzyskasz takie slicznosci jak boost::bind, boost::lambda::bind, boost::memfn itp. jesli nie chcesz zmieniac jezyka,polecalbym Ci juz teraz zaczac sciagac i kompilowac boosta, a w miedzy czasie zaznajomic sie ze skladnia pointer-to-member. potemwziac boost'a i jego dodatki wspomagajce w obroty. a jak chcesz zmieniac jezyk to najpierw poznaj C++ potem C#, a dopiero potem wez sie za C++/CLI, inaczej moze byc ciezko zrozumiec niektore rzeczy..

chłopie, jakie cli? Native C++ - mowi Ci to cos?

__events jest zwyklym rozszerzeniem c++ i kompiluje sie i dziala bez cli

poza tym co opisalem uzywalem jeszcze FastDelegates, a biblioteki typu boost nie nadaja sie do moich zastosowan (za duzy rozrost pliku)

0

hm.. rzeczywiscie nie cli.. uznalem ze to cli jak tylko zobaczylem "event" :) ciekawe, nie wiedzialem ze przyokazji takze zrobili je w trybie native. niemniej, bez wsparcia ze strony kompilatora raczej czegos takiego nie uzyskasz.. probowales w ogole uzywac boosta? (swoja droga realizacja z hook, __rasise itp bardzo mi przypomina to co mozna boost'em uzyskac.. tylko ladniej wyglada) czesc boosta ktorej bys potrzebowal jest header-only, mozna sobie spokojnie 'pozyczyc' tylko te pare naglowkow. same niewielkie template'y, ladnie sie optymalizuja.. nie wiem co rozumiesz przez duzy rozrost pliku, ja binderow i wrapperow na metody czesto korzystam i nie zauwazylem.. ale to oczywiscie tempalte'y to template'y wiec jednak jest duplikacja kodu per-specjalizacja..

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0