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..