Funkcja jako argument innej funkcji

0

Witam,oto moj problem
mam pewna klase druzyna oraz interfejs,oraz chce wywolac pewna funkcje oto kawalek kodu:


typedef void (*vcall)(druzyna A,druzyna B,druzyna C,druzyna D);

int interfejs::menu_glowne(vcall menu_wyswietlania_druzyn,druzyna A,druzyna B,druzyna C,druzyna D)
{
...
menu_wyswietlania_druzyn(A, B, C, D);
...
}

void interfejs::menu_wyswietlania_druzyn(druzyna A,druzyna B,druzyna C,druzyna D)
{
...
}


//kawalek maina:

        interfejs intf;
	intf.ekran_powitalny();
	intf.menu_glowne(intf.menu_wyswietlania_druzyn,Arsenal,Barcelona,Manchester_United,Real_Madryt);

moje pytanie brzmi jak wywolac to funkcji main zeby dzialalo?

otrzymuje taki blad error C3867: 'interfejs::menu_wyswietlania_druzyn': function call missing argument list; use '&interfejs::menu_wyswietlania_druzyn' to create a pointer to member

musze zrobic wskaznik lecz nie bardzo mam pomysl jak to zrobic,prosze o pomoc

0

Ale u mnie nie ma skladnikow prywatnych,nie dalem rady rozgryźć tego za pomoca tego linku,prosze o podpowiedz

0

Tu chodzi nie o prywatność zaś o to co opisano w tym linku.
Masz niepoprawnie zadeklarowany wskaźnik na metodę.

0

gdyby funkcja nie była składowa tylko globalna to program by zadziałał poprawnie gdyż właśnie taki wskaźnik zadeklarowałeś na jakąś funkcję globalną. Najprawdopodobniej musisz się posłuzyć operatorem zakresu. Łap linka: http://firsthost.nazwa.pl/wordpress/2009/08/06/wskazniki-na-metody-w-c/.
Dobra podam ci rozwiązanie na podstawie tego linku i powinno zadziałać:

typedef void (interfejs::*vcall)(druzyna A,druzyna B,druzyna C,druzyna D);
 
int interfejs::menu_glowne(vcall menu_wyswietlania_druzyn,druzyna A,druzyna B,druzyna C,druzyna D)
{
...
(this->*menu_wyswietlania_druzyn)(A, B, C, D);
...
}
 
void interfejs::menu_wyswietlania_druzyn(druzyna A,druzyna B,druzyna C,druzyna D)
{
...
}
 
 
//kawalek maina:
 
        interfejs intf;
    intf.ekran_powitalny();
    intf.menu_glowne(&interfejs::menu_wyswietlania_druzyn,Arsenal,Barcelona,Manchester_United,Real_Madryt);

//edit
Teraz na 100% działa.

2

@robcio, nie powinno zadziałać, wywoływanie metod przez wskaźnik odbywa się za pomocą operatorów .* lub ->*

0

to może tak:

struct Bar {
    typedef void (Bar::*MemPtr)(int, int, int);
    typedef std::function<void(int, int, int)> MemPtr2;

    void foo(MemPtr ptr, Bar & bar, int a, int b, int c);
    void foo2(MemPtr2 ptr, int a, int b, int c);
    void member(int a, int b, int c);

};

void Bar::foo(MemPtr ptr, Bar & bar, int a, int b, int c)
{
    (bar.*ptr)(a, b, c);
}

void Bar::foo2(MemPtr2 ptr, int a, int b, int c)
{
    ptr(a, b, c);
}


void Bar::member(int a, int b, int c)
{
    std::cout << a << ' ' << b << ' ' << c << "\r\n";
}

int main()
{
    Bar b;

    b.foo(&Bar::member, b, 2, 3, 4);
    b.foo2(std::bind(&Bar::member, &b,
                     std::placeholders::_1,
                     std::placeholders::_2,
                     std::placeholders::_3), 3, 4, 5);
    return 0;
}
0

@_13th_Dragon dobra rozwiązałem problem wystarczy dodać this przed wywołaniem metody i gitara kompiluje się bez problemów: http://ideone.com/VqXbBp

1
robcio napisał(a):

wystarczy dodać this przed wywołaniem metody

Według mnie dla przypadku ogólniejszego to nie jest dobre rozwiązanie. W tym przypadku działa zgodnie z zamiarem ponieważ widać, że autor ma zamiar wywoływać metodę tego samego obiektu, do którego przekazuje wskaźnik. Ale czy zawsze autor będzie chciał aby ta metoda była wywoływana dla tego samego obiektu, do którego przekazuje wskaźnik? Jak tak to dla mnie nie ma to sensu. Natomiast sens miałoby przekazanie wskaźnika na metodę innego obiektu, która np. zmieniałaby jego stan.

Może poniższy kod wyjaśni co mam na myśli:

#include <iostream>

struct Bar {
    typedef void (Bar::*MemPtr)(int);

    Bar(const std::string & name_) : name(name_), x(-1){}

    void foo(MemPtr ptr, Bar & bar, int a);
    void foo2(MemPtr ptr, int a);
    void member(int a);

    std::string name;
    int x;
};

void Bar::foo(MemPtr ptr, Bar & bar, int a)
{
    (bar.*ptr)(a);
}

void Bar::foo2(MemPtr ptr, int a)
{
    (this->*ptr)(a);
}

void Bar::member(int a)
{
    x = a;
    std::cout << "Wywolano metode Bar::member obiektu: " << name << "\r\n";

}

int main()
{
    {
        Bar b("obiekt1");
        Bar b2("obiekt2");

        b.foo(&Bar::member, b, 1);
        std::cout << "(foo)obiekt1.x = " << b.x << "\r\n";
        std::cout << "(foo)obiekt2.x = " << b2.x << "\r\n";

        b2.foo(&Bar::member, b, 3);
        std::cout << "(foo)obiekt1.x = " << b.x << "\r\n";
        std::cout << "(foo)obiekt2.x = " << b2.x << "\r\n";
    }

    std::cout << "\r\n";

    {
        Bar b("obiekt1");
        Bar b2("obiekt2");

        b.foo2(&Bar::member, 1);
        std::cout << "(foo2)obiekt1.x = " << b.x << "\r\n";
        std::cout << "(foo2)obiekt2.x = " << b2.x << "\r\n";

        b2.foo2(&Bar::member, 3);
        std::cout << "(foo2)obiekt1.x = " << b.x << "\r\n";
        std::cout << "(foo2)obiekt2.x = " << b2.x << "\r\n";
    }
    return 0;
}

wyjście:

Wywolano metode Bar::member obiektu: obiekt1
(foo)obiekt1.x = 1
(foo)obiekt2.x = -1
Wywolano metode Bar::member obiektu: obiekt1
(foo)obiekt1.x = 3
(foo)obiekt2.x = -1

Wywolano metode Bar::member obiektu: obiekt1
(foo2)obiekt1.x = 1
(foo2)obiekt2.x = -1
Wywolano metode Bar::member obiektu: obiekt2
(foo2)obiekt1.x = 1
(foo2)obiekt2.x = 3

W waszym przypadku jestem ograniczony tylko do tego jednego obiektu.

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