wskaźnik na niestatyczną metodę

0

Hej!

Z czysto ambicjonalnych pobudek chciałbym sobie poradzić z następującym problemem. Mam klasę abstrakcyjną ALG, po której dziedziczą P i IS. Klasa ALG potrzebuję, by zawierała wskaźnik na którąś ze swoich niestatycznych metod. Generalnie działa to tak, że użytkownik wybiera formę wprowadzania danych do tablicy (ręcznie, z pliku, losowo) a następnie switchem znajdującym się w main() chciałbym wykonywać coś w stylu

obiekt->akcja = obiekt->getFromUser();

na różne metody.

następnie uruchomiena chciałbym żeby została ta metoda z run() w klasie IS() lub P():

public run() {
   akcja();
   posortuj();
   printWyniki();
}

Mam nadzieję, że do tej pory jasne. Wiem, że mozna prosciej (np. chcialem umiescic switcha w klasie i przekazywac tam wynik wyboru uzytkownika, ale to wydaje mi sie prostackie), ale jak juz mowilem, chcialbym się i tego nauczyc. Do tej pory kod jaki stworzyłem i nie bardzo mi działa:

typedef void (ALG::* wskMetoda)();

class ALG {
public:
	wskMetoda Akcja;

	void generateRandomData(){}
        void getFile() {}
        void getFromUser() {}
	void printResults() { }
};

class P : public ALG {
public:
	void run() {
            Akcja();
            wyniki[a]=partition(0,rozmiar-2);
            printResults();
        }
    int partition(int lewa, int prawa){}
};

class IS : public ALG {
public:
    int sort() { }
    void run() {
        akcja();
	wyniki[a]=sort();
	printResults();
    }
};

int _tmain(int argc, _TCHAR* argv[]){

    scanf("%d",wybor);
		switch(wybor) {
			case 1:
				obiekt->akcja = obiekt->getFromUser();
				break;
			case 2:
				obiekt->akcja = obiekt->generateRandomData();
				break;
			case 3:
				obiekt->akcja = obiekt->setData(tab);
				break;
			case 4:
				obiekt->akcja = obiekt->getFile();
				break;
		}

	obiekt->run();
}

Oczywiście ten kod nie ruszy, mocno go okroiłem, chodzi mi raczej o zaprezentowanie mniej więcej struktury programu. Bardzo byłbym wdzięczny osobom, które są w stanie mi pomóc z nauczenie się jak konstruować i posługiwać się pointer to nonstatic member ;) Niestety wszystkie przykłady które sa na google albo są bez użycia klas, albo nie ma do nich dostępu z zewnątrz. No chyba, że jestem ślepy i nic nie widzę (w cpp próbuję sił od paru miesięcy dopiero). Z góry dzięki!!!!!!!

0

Jeśli to Builder to spróbuj:

typedef void (__closure ALG::* wskMetoda)();
0

Niestety, VS2k8

0

źle wywołujesz tą akcję, powinno być tak:

this->(*Akcja)();

Po drugie, do takiego wskaźnika nie wolno przypisać metody z klasy pochodnej (bo nie da się "skonwertować automatycznie wskaźnika this"). Musisz wymusić konwersję jeśli chcesz by to było możliwe.

0
MarekR22 napisał(a)

źle wywołujesz tą akcję, powinno być tak:

this->(*Akcja)();

Po drugie, do takiego wskaźnika nie wolno przypisać metody z klasy pochodnej (bo nie da się "skonwertować automatycznie wskaźnika this"). Musisz wymusić konwersję jeśli chcesz by to było możliwe.

Dla this->(*Akcja)(); dostaję błąd syntax: "("

i jeszcze całą mase innych błędow (wklejam po poście).

A jesli dam ten wskaznic w obu pochodnych zamiast w bazowej ?

Error	3	error C2059: syntax error : '('	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	155	Insertion Sort
Error	4	error C2039: 'a' : is not a member of 'P'	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	156	Insertion Sort
Error	5	error C2597: illegal reference to non-static member 'ALG::wyniki'	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	156	Insertion Sort
Error	6	error C3867: 'ALG::wyniki': function call missing argument list; use '&ALG::wyniki' to create a pointer to member	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	156	Insertion Sort
Error	7	error C2597: illegal reference to non-static member 'ALG::rozmiar'	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	156	Insertion Sort
Error	8	error C3867: 'ALG::rozmiar': function call missing argument list; use '&ALG::rozmiar' to create a pointer to member	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	156	Insertion Sort
Error	9	error C2352: 'P::partition' : illegal call of non-static member function	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	156	Insertion Sort
Error	10	error C2352: 'ALG::printResults' : illegal call of non-static member function	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	158	Insertion Sort
Error	11	error C2597: illegal reference to non-static member 'ALG::data'	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	162	Insertion Sort
Error	12	error C3867: 'ALG::data': function call missing argument list; use '&ALG::data' to create a pointer to member	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	162	Insertion Sort
....
Error	56	error C2146: syntax error : missing ';' before identifier 'Akcja'	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	190	Insertion Sort
Error	57	error C4430: missing type specifier - int assumed. Note: C++ does not support default-int	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	190	Insertion Sort
Error	58	error C4430: missing type specifier - int assumed. Note: C++ does not support default-int	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	190	Insertion Sort
Error	59	error C2039: 'podstawienia' : is not a member of 'P'	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	196	Insertion Sort
Error	60	error C2039: 'a' : is not a member of 'P'	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	197	Insertion Sort
Error	61	error C2039: 'a' : is not a member of 'P'	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	197	Insertion Sort
Error	62	error C2597: illegal reference to non-static member 'ALG::rozmiar'	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	197	Insertion Sort
Error	63	error C3867: 'ALG::rozmiar': function call missing argument list; use '&ALG::rozmiar' to create a pointer to member	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	197	Insertion Sort
Error	64	error C2568: '<' : unable to resolve function overload	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	197	Insertion Sort
0

spróbuj tak:

(this->*Akcja)();

W tym miejscu zawsze mylę, gdzie mają być nawiasy.
Zresztą patrząc na typedef już widać jak powinno być z tymi nawiasami.

0

Marku, faktycznie pomogło, tylko teraz mi pokazuje, że dla

obiekt->Akcja=obiekt->getFromUser();
Error	5	error C2440: '=' : cannot convert from 'void' to 'ALG::wskMetoda'	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	250	Insertion Sort

Tak do mnie dotarło, że chyba zapomniałem o referencji

obiekt->Akcja=&obiekt->getFromUser();

ale po takiej operacji wywala mi

Error	5	error C2102: '&' requires l-value	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	242	Insertion Sort
0
obiekt->Akcja=&Alg::getFromUser;
0

wszystko byłoby ok, gdyby nie to że pytam specjalnie w temacie o NIE-statyczne metody ;) no albo ja jestem głupi i nie kumam tego, w każdym razie po zmianie jak napisałeś mam błąd

Error	5	error C2352: 'ALG::getFromUser' : illegal call of non-static member function	d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp	242	Insertion Sort

jeżeli dodam parametr static do metod to pewnie ruszy, pytanie tylko czy i jak sie zachowaja jezeli kazda z nich operuje na jakichś tam atrybutach klas... pewnie nie zadziała?

0
uirapuru napisał(a)

wszystko byłoby ok, gdyby nie to że pytam specjalnie w temacie o NIE-statyczne metody ;)
Ale właśnie w taki sposób się wyciąga wskaźnik na niestatyczną metodę klasy.

0
Fanael napisał(a)
uirapuru napisał(a)

wszystko byłoby ok, gdyby nie to że pytam specjalnie w temacie o NIE-statyczne metody ;)
Ale właśnie w taki sposób się wyciąga wskaźnik na niestatyczną metodę klasy.

no to już nie wiem, potrzebuje, żeby mnie ktoś poprowadził za rączkę i powiedział, co teraz

0

obadaj boost bind, boost signal, libsigc++ itp wynalazki ;)

0

to dodatkowe biblioteki, tak? wcześniej juz o nich gdzieś czytałem, ale miałem nadzieję, że obejdzie się bez

0

wklejam cały kod, jeśli ktokolwiek może mi pomóc...

// Insertion Sort.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#include "math.h"
#include "string"
#include "iostream"
#include "fstream"
#include "cstdlib"
using namespace std;

class ALG {
public:
	int counter;
    int * wyniki;
    int rozmiar;
    int * data;
    char * mode;
	int wybor;
	int * tab;
	int podstawienia_indx;
	typedef void (ALG::* wskMetoda)();
	wskMetoda Akcja;

	ALG() {
    }

	ALG(int size, int c) {
		setTabSize(size);
        setCountSize(c);
        data = new int[rozmiar+1];
        data[rozmiar] = INT_MAX;
		wyniki = new int[counter+1];
		podstawienia_indx = 0;
		srand(time(0));

		tab = new int[rozmiar];
		for(int a=0; a<10; a++){
			tab[a] = 11*a;
		}
    }
	void akcaja() {
		switch(wybor) {
			case 1:
				getFromUser();
				break;
			case 2:
				//obiekt->generateRandomData();
				generateRandomData();
				break;
			case 3:
				setData(tab);
				break;
			case 4:
				getFile();
				break;
			default:
				getFromUser();
				break;
		}
	}
	void setData(int * array) {
        mode = "Predefined";
        for(int a=0; a<rozmiar; a++) {
            data[a] = array[a];
        }
    }

    void generateRandomData() {
        mode = "Random";
        for(int a = 0; a<rozmiar; a++) {
            data[a] = (rand()*rand())%111;
        }
    }

    void getFile() {
        mode = "Z pliku";
        ifstream odczyt;
        int a,b = 0;

        odczyt.open("tablica.txt");
        while (!odczyt.good()) {
            printf("blad w odczytywaniu pliku\n");
            exit(0);
        }
        odczyt >>skipws;

        while (odczyt.good()) {
            odczyt>>a;
            data[b++] = a;
        }
        odczyt.close();
    }

    void getFromUser() {
        mode = "User";
        system("cls");
        for(int a = 0; a<rozmiar; a++) {
            printf("Podaj element [%d] => ",a);
            scanf("%d",&data[a]);
        }
    }
    virtual void run() {
	}
	void printResults() {
		printf("\npowtorzen: %d",counter);
        printf("\nsrednia: %f",srednia());
        printf("\nodchylenie: %f",odchylenie());
		printf("\n\n");
    }
    virtual void setTabSize(int size) {
        rozmiar = size;
    }
    void setCountSize(int size) {
        counter = size;
    }
    void printData() {
        printf("\n\nTablica typu: %s [%d]\n",mode,rozmiar);
        for(int a = 0; a<rozmiar; a++) {
            printf("[%d] => %d\n",a,data[a]);
        }
    }
    float srednia() {
        float wynik=0.0;
        for(int a=0; a<rozmiar; a++) {
            wynik+=wyniki[a];
        }
        return wynik/counter;
    }
	float odchylenie() {
        float odchylenie=0.0;
        float roznica=0.0;
        for (int i=0; i < rozmiar; i++) {
            roznica = wyniki[i] - srednia();
            odchylenie += pow(roznica, 2);
        }
        odchylenie /= rozmiar;
        return sqrt(odchylenie)/(counter-1);
    }
};

class P : public ALG {
public:
	P(int size, int c);

	void run() {
        for(int a=0; a<counter; a++) {    
            (this->*Akcja)();
            wyniki[a]=partition(0,rozmiar-2);
        }
		printResults();
    }

    int partition(int lewa, int prawa){
        int value = data[0];
        int i = lewa;
        int j = prawa + 1;
        int temp;

        do {
            do {
                i++;
            } while (data[i] <= value);
            do {
                j--;
            } while (data[j] >= value && j>0);
            if (i <= j) {
                temp = data[i];
                data[i] = data[j];
                data[j] = temp;
            }
        } while (j >= i );

        data[lewa] = data[j];
        data[j] = value;
        return j;
    }
};

class IS : public ALG {
public:
	IS(int size, int c);
    int sort() {
        int liczba,a,b, podstawienia;
		podstawienia = 0;
        for(a=1; a<rozmiar; a++){ // zaczynamy porównywanie od elementu 2 w tablicy
            liczba = data[a]; // zapamiętujemy element
            b=a-1;                  // ustawiamy sobie poprzedni element
            while(data[b]>liczba && b>=0) { // dopóki element poprzedni jest większy od następnego
            data[b+1]=data[b]; // przesuwamy poprzedni w dół
			podstawienia++;
            b--;
        }
        data[b+1] = liczba; // wstawiamy zapamiętany element
        }
		return podstawienia; // zwraca ilosc podstawien
    }

    void run() {
    	for(int a=0; a<counter; a++) {
			(this->*Akcja)();
			wyniki[a]=sort();
		}
		printResults();
    }
};






int _tmain(int argc, _TCHAR* argv[]){
    do {
    int wybor;

    system("cls");
    printf("## Sortowanie tablic ##\n## Grzegorz  Kaszuba ##\n\nWybierz algorytm:\n 1\\ Insertion Sort\n 2\\ Partition\n\nwybor: ");
    scanf("%d",&wybor);

    ALG * obiekt;
    IS insertionsort(10, 100);
    P partition(10, 100);

	switch(wybor) {
		case 1:
				obiekt =&insertionsort;
				break;
		case 2:
				obiekt = &partition;
				break;
		default:
			printf("Podano niewlasciwy algorytm sortowania!\n");
			return 0;
	}

	printf("\nWybierz typ danych:\n 1\\ wprowadz dane recznie\n 2\\ losowe dane\n 3\\ predefiniowane dane\n 4\\ dane z pliku tablica.txt\n\nwybor: ");
    scanf("%d",wybor);

		switch(wybor) {
			case 1:
				obiekt->Akcja=&obiekt->getFromUser();
				break;
			case 2:
				obiekt->Akcja=&obiekt->generateRandomData();
				break;
			case 3:
				//obiekt->Akcja=obiekt->setData(tab);
				break;
			case 4:
				obiekt->Akcja=&obiekt->getFile();
				break;
			default:
				obiekt->Akcja=&obiekt->getFromUser();
				break;
		}

	obiekt->run();

    system("pause");
    } while (1==1);

    return 0;
}
0
// Insertion Sort.cpp : Defines the entry point for the console application.
//
//#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#include "math.h"
#include "string"
#include "iostream"
#include "fstream"
#include "cstdlib"

using namespace std;

class ALG
{
protected:
    int rozmiar;
    int * data;

    int counter;
    int * wyniki;

    typedef void (ALG::* wskMetoda)();
    wskMetoda Akcja;

private:
    char const * mode;

public:
    //q: ALG nie potrzebuje domyslnego nic nierobiacego konstruktora

    ALG(int size, int c) :
        rozmiar(size),               //q: jesli chcesz miec
        data(new int[rozmiar+1]),    //q: ladny, c++owy program
        counter(c),                  //q: to co mozesz, inicjalizuj za pomoca
        wyniki(new int[counter+1])   //q: listy inicjalizacyjnej
    {
        data[rozmiar] = INT_MAX;
        srand(time(0));
    }

    ~ALG() //q: swiat bedzie Ci wdzieczny, jak bedziesz po sobie sprzatac wlasne smieci
    {
        delete[] wyniki; wyniki=0;
        delete[] data; data=0;
    }

private:
    void printData()
    {
        printf("\n\nTablica typu: %s [%d]\n", mode, rozmiar);
        for(int a = 0; a<rozmiar; a++)
            printf("[%d] => %d\n", a, data[a]);
    }

    float srednia()
    {
        float wynik=0.0;
        for(int a=0; a<rozmiar; a++) wynik+=wyniki[a]; // q: zastanow sie nad tym, co jest rozmiarem tablicy 'wyniki'
        return wynik/counter;
    }

    float odchylenie()
    {
        float odchylenie=0.0;
        float roznica=0.0;
        for (int i=0; i < rozmiar; i++)
        {
            roznica = wyniki[i] - srednia(); // q: zastanow sie nad tym, co jest rozmiarem tablicy 'wyniki'
            odchylenie += pow(roznica, 2);
        }
        odchylenie /= rozmiar;
        return sqrt(odchylenie) / (counter-1); // q: sprawdz czy faktycznie -1 przy counter
    }

public:
    // q: metoda virtual przeznaczona do wypelnienia przez klasy-dzieci moze byc pure virtual
    // q: i w ogole nie miec wlasnego ciala.
    // q: po co? sprobuj teraz napisac klase-dziecko ktore nie ma wlasnej metody run!
    virtual void run() = 0;

    void setAkcja(wskMetoda akcja) { Akcja = akcja; }
    
    void generateRandomData()
    {
        mode = "Random";
        for(int a = 0; a<rozmiar; a++)
            data[a] = (rand()/**rand()*/) % 111; //q: skoro modulo 111, to po co rand()*rand()? RAND_MAX jest >> 111
    }

    void getFromUser()
    {
        mode = "User";
        system("cls");
        for(int a = 0; a<rozmiar; a++)
        {
            printf("Podaj element [%d] => ",a);
            scanf("%d", &data[a]); //q: nie sprawdzasz czy scanf zwrocil '1' - tzn. czy wpisano poprawne dane
        }
    }

    void getFile()
    {
        mode = "Z pliku";

        ifstream odczyt = ifstream("tablica.txt");
        while (!odczyt.good())
        {
            printf("blad w odczytywaniu pliku\n");
            exit(0);
        }

        // odczyt >> skipws; // q: o ile dobrze pamietam, to juz jest defaultowo na strumieniu

        int a, b = 0;
        while (odczyt.good())
        {
            odczyt >> a; // q: jezeli 'ostatni' odczyt sie nie powiedzie, linia ponizej wstawi smieci do tablicy
            data[b++] = a; // q: a co jezeli liczb jest wiecej niz rozmiar data[]? tzn. gdy b > rozmiar ?
        }
        
        // q: a co jesli liczb w pliku bylo mniej niz rozmiar?

        odczyt.close();
    }

    void printResults()
    {
        printf("\npowtorzen: %d", counter);
        printf("\nsrednia: %f", srednia());
        printf("\nodchylenie: %f", odchylenie());
        printf("\n\n");
    }
};

class P : public ALG
{
public:
    // q: tak powinien wygladac konstruktor klasy dziedziczacej
    // q: listy inicjalizacyjne sa fajne, gdyz pozwalaja Ci skorzystac z
    // q: argumentowego konstruktora bazowego
    P(int size, int c) : ALG(size, c) { } //q: te klamry musza tutaj byc, nawet jesli w nich w srodku nic nie ma. metoda musi miec cialo, albo byc pure virtual

    void run()
    {
        for(int a=0; a<counter; a++)
        {
            (this->*Akcja)();
            wyniki[a]=partition(0, rozmiar-2); // q: sprawdz czy faktycznie -2 przy rozmiar
        }
        printResults();
    }

    int partition(int lewa, int prawa) // q: przyznam, nie chcialo mi sie sprawdzac
    {
        int value = data[0];
        int i = lewa;
        int j = prawa + 1;
        int temp;

        do
        {
            do i++; while (data[i] <= value);
            do j--; while (data[j] >= value && j>0);
            
            if (i <= j)
            {
                temp = data[i];
                data[i] = data[j];
                data[j] = temp;
            }
        } while (j >= i);

        data[lewa] = data[j];
        data[j] = value;

        return j;
    }
};

class IS : public ALG
{
public:
    // q: tak powinien wygladac konstruktor klasy dziedziczacej
    // q: listy inicjalizacyjne sa fajne, gdyz pozwalaja Ci skorzystac z
    // q: argumentowego konstruktora bazowego
    IS(int size, int c) : ALG(size, c) { }

    int sort() // q: przyznam, nie chcialo mi sie sprawdzac
    {
        int liczba,a,b, podstawienia;
        podstawienia = 0;
        for(a=1; a<rozmiar; a++)            // zaczynamy porównywanie od elementu 2 w tablicy
        {
            liczba = data[a];                // zapamiętujemy element
            b=a-1;                            // ustawiamy sobie poprzedni element
            while(data[b]>liczba && b>=0)    // dopóki element poprzedni jest większy od następnego
            {
                data[b+1]=data[b];            // przesuwamy poprzedni w dół
                podstawienia++;
                b--;
            }
            data[b+1] = liczba;                // wstawiamy zapamiętany element
        }
        return podstawienia;                // zwraca ilosc podstawien
    }

    void run()
    {
        for(int a=0; a<counter; a++)
        {
            (this->*Akcja)();
            wyniki[a]=sort();
        }
        printResults();
    }
};

int main(int argc, char* argv[])
{
    do
    {
        int wybor;

        system("cls");
        printf("## Sortowanie tablic ##\n"
                "## Grzegorz  Kaszuba ##\n\n"
                "Wybierz algorytm:\n"
                " 1\\ Insertion Sort\n"
                " 2\\ Partition\n\nwybor: ");
        scanf("%d",&wybor);

        ALG * sortowacz = 0;
        //q: skoro juz operujesz na ALG* to po co tworzyc w ciemno obiekty i potem brac ptr na nie?

        switch(wybor)
        {
            case 1: sortowacz = new IS(10, 100); break; //q: po prostu stworz sobie dany obiekt dynamicznie
            case 2: sortowacz = new P (10, 100); break; //q:  w momencie w ktorym wiesz ze akurat on bedzie Ci dalej potrzebny
            default: printf("Podano niewlasciwy algorytm sortowania!\n"); return 0;
        }
        // q: btw. jestes pewien ze chcesz miec size=10 oraz counter=100?
        // q: jesli tak, powodzenia przy petlach for(int a=0; a<counter; a++) akcja() gdy akcja = pobierzodusera

        printf("\nWybierz typ danych:\n"
                " 1\\ wprowadz dane recznie\n"
                " 2\\ losowe dane\n"
                //q: ciach
                " 4\\ dane z pliku tablica.txt\n\n"
                "wybor: ");
        scanf("%d",wybor);

        switch(wybor)
        {
            case 1:        sortowacz->setAkcja( &ALG::getFromUser ); break;
            case 2:        sortowacz->setAkcja( &ALG::generateRandomData ); break;
            //q: ciach
            case 4:        sortowacz->setAkcja( &ALG::getFile ); break;
            default:    sortowacz->setAkcja( &ALG::getFromUser ); break;
        }

        sortowacz->run();

        system("pause");
        
        delete sortowacz; sortowacz=0; //q: warto by bylo po sobie jeszcze posprzatac te dynamiczne obiekty
    
    } while (1==1);

    return 0;
}

To Ci sie skompiluje i wyglada jakby moglo dzialac poprawnie. Nie sprawdzalem czy dziala poprawnie, wiec pewnie tak nie jest, jednak fragmenty ktore zmienilem sa prawieze na pewno poprawne i jesli nie dzialaja - zaloz ze nie dzialaja przez bledy pozostawione w innych miejscach Tobie do przemyslenia. Nie bede opisywal co zmienilem, gdyz to bez sensu, uzyj Diff'a jesli masz problemy ze znalezieniem roznic. Popozostawialem Ci mase komentarzy gdzie mozeszmiec/pewniemasz jakies wpadki jeszcze. To na pewno nie sa wszystkie. Czesci kodu nie chcialo mi sie ogladac, a te ktore akurat obejrzalem - nie analizowalem zbyt doglebnie.

0

quetzalcoatl: odzyskalem dzięki Tobie w wiare w programistyczną sztukę, a nie bibliotekowe rzemiosło ;) dzięki serdeczne, program fruwa. Nauczylem się przy okazji troche używac wskaźników i o listach inicjalizacyjnych :) DZIĘKUJĘ!!!

0
uirapuru napisał(a)
MarekR22 napisał(a)

źle wywołujesz tą akcję, powinno być tak:

this->(*Akcja)();

Po drugie, do takiego wskaźnika c**** wolno przypisać metody z klasy pochodnej (bo nie da się "skonwertować automatycznie wskaźnika this"). Musisz wymusić konwersję jeśli chcesz by to c**** możliwe.

Dla this->(*Akcja)(); dostaję błąd syntax: "("

i jeszcze całą mase innych błędow (wklejam po poście).

A jesli dam ten wskaznic w obu pochodnych zamiast w bazowej ?

Error 3 error C2059: syntax error : '(' d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 155 Insertion Sort
Error 4 error C2039: 'a' : is not a member of 'P' d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 156 Insertion Sort
Error 5 error C2597: illegal reference to non-static member 'ALG::wyniki' d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 156 Insertion Sort
Error 6 error C3867: 'ALG::wyniki': function call missing argument list; use '&ALG::wyniki' to create a pointer to member d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 156 Insertion Sort
Error 7 error C2597: illegal reference to non-static member 'ALG::rozmiar' d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 156 Insertion Sort
Error 8 error C3867: 'ALG::rozmiar': function call missing argument list; use '&ALG::rozmiar' to create a pointer to member d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 156 Insertion Sort
Error 9 error C2352: 'P::partition' : illegal call of non-static member function d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 156 Insertion Sort
Error 10 error C2352: 'ALG::printResults' : illegal call of non-static member function d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 158 Insertion Sort
Error 11 error C2597: illegal reference to non-static member 'ALG::data' d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 162 Insertion Sort
Error 12 error C3867: 'ALG::data': function call missing argument list; use '&ALG::data' to create a pointer to member d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 162 Insertion Sort
....
Error 56 error C2146: syntax error : missing ';' before identifier 'Akcja' d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 190 Insertion Sort
Error 57 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 190 Insertion Sort
Error 58 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 190 Insertion Sort
Error 59 error C2039: 'podstawienia' : is not a member of 'P' d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 196 Insertion Sort
Error 60 error C2039: 'a' : is not a member of 'P' d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 197 Insertion Sort
Error 61 error C2039: 'a' : is not a member of 'P' d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 197 Insertion Sort
Error 62 error C2597: illegal reference to non-static member 'ALG::rozmiar' d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 197 Insertion Sort
Error 63 error C3867: 'ALG::rozmiar': function call missing argument list; use '&ALG::rozmiar' to create a pointer to member d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 197 Insertion Sort
Error 64 error C2568: '<' : unable to resolve function overload d:\Moje dokumenty\Visual Studio 2008\Projects\Insertion Sort\Insertion Sort\Insertion Sort.cpp 197 Insertion Sort

0

niedawno sam mialem z tym problem. najpierw definiujemy sobie typ akcji:

typedef void (klasanadrzedna::*akcja)();

w środku klasy:

akcja zdarzenie;

przypisanie akcji klasie pochodnej/nadrzednej (w jakiejs funkcji klasy pochodnej/nadrzednej):

klasanadrzedna::zdarzenie = (klasanadrzedna::akcja)(&klasapodrzedna::funkcja);

przypisanie akcji klasie pochodnej/nadrzednej (poza funkcja klasy pochodnej/nadrzednej), chyba tak (bo nie mialem potrzeby uzycia):

nazwaobiektu.klasanadrzedna::zdarzenie = (klasanadrzedna::akcja)(&klasapodrzedna::funkcja);

wywołanie w klasie pochodnej/nadrzednej:

(this->*zdarzenie)();

wywolanie poza klasa pochodna/nadrzedna:

(obj->*(obj->zdarzenie))();

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