wskaznik na metode klasy A dostepny w klasie B

0

Witam
Dziś stanąłem przed takim oto problemem ( opisze go schematycznie to bedzie chyba najszybciej ):

class A
{
     public:
              A();
              bool ( A::*wsk_funct )( void );
              bool funkcja( void );
};

A::A()
{
    wsk_funct = &A::funkcja;
}

class B
{
    public:
             void foo( A* obiekt );
};

void B::foo( A* obiekt )
{
   bool sth = obiekt -> wsk_func();
}

Przy próbie kompilacji czegoś w tym stylu dostaje komunikat:
must use .* or ->* to call pointer-to-member function in " obiekt -> A::funkcja(..)"
Oczywiście to co chciał bym uzyskać to właśnie dostęp do wskaźnika klasy A wskazującego na metodę klasy A z wnętrza metody klasy B.
Proszę pomóżcie.
Z góry dziękuję.

Edit:
Aha jak coś to używam kompilatora MinGw

0

Tego w ten sposób nie zrobisz bo metoda różni się od funkcji tym, że ma niejawnie przekazywany this i to on wszystko utrudnia. Użycie takiego wskaźnika mogłoby wyglądać tak:

class A;

typedef void(A::*memberPointer)();

class A {
    public:
        A(){ p = &A::f; }
        void f(){ cout << "cos";}
        void tp() { (this->*p)(); } //tutaj
        memberPointer p;
};

Nie uda ci się go wywołać z innej klasy, musisz opakować go w metode, a wtedy mija się to z celem i jest bezsensowne.
Możesz jednak pokombinować w inny sposób, nie jestem pewny czy nie da się tego rozwiązać przy pomocy szablonów i callback'ów.

0

Możesz też zrobić tą metodę statyczną i w tedy nie ma problemów bo nie jest wywoływana na rzecz obiektu lub kompilować w jakimś kompilatorze, który rozszerza możliwości c++ np. borland i jego __closure, które rozwiązuje ten problem.

0

http://www.parashift.com/c++-faq-lite/pointers-to-members.html

edit:
Co do oryginalnego kodu:

#include <iostream>

class A {
public:
    int foo() const {
        return 666;
    }
};

class B {
    typedef int (A::*MethodPtr)() const;
    MethodPtr ptr;
    
public:
    B () : ptr(&A::foo) {}
    
    int bar(const A& obj) {
        return (obj.*ptr)();
    }
};

int main() {
    A a;
    B b;
    std::cout << b.bar(a) << "\n";
    
    return 0;
}
0

Wielkie dzięki Azrael_Valedhel wprawdzie wpadłem na połowę rozwiązania ale nie potrafiłem się do niego odwołać więc bez Ciebie to bym sobie nie poradził.
A skoro już tutaj jestem to chciał bym was jeszcze zapytać czy dopuszczaalne jest coś takiego:

class A
{
    // stuff
};
int main()
{
    A* a = new A(); // o tą linijke mi chodzi

}

I kiedy powinno się tego używać a kiedy nie.
Jeszcze raz dzięki.

ps: Borland z ta swoja super opcja _cloasure() - czy jak to sie pisze, był by dobrym rozwiazaniem ale dzialam na starym rupieci i mysle ze bylby problem z jego uruchomieniem.

0

a jest wskaźnikiem na obiekt klasy A.
new alokuje pamięć dla obiektu klasy A, wywołuje jego konstruktor (inicjalizuje vtable) i zwraca adres. Do każdego new zawsze musi być delete, aby wywołać destruktor i zwolnić pamięć!* ;)
Zmienne automatyczne są na stosie (stack), a tworzone przez new na stercie (heap). (Dlaczego to ma znaczenie? "stack unwinding")

Kiedy się powinno używać? Polimorfizm działa na referencjach i wskaźnikach, to już Ci powinno kilka pomysłów przywieść na myśl.

*) Jednak łatwiej jest użyć sprytnego wskaźnika (smart pointer), który sam po sobie posprząta. ;)

http://stackoverflow.com/questions/599308/proper-stack-and-heap-usage-in-c
http://ee.hawaii.edu/~tep/EE160/Book/chap14/subsection2.1.1.8.html
http://stackoverflow.com/questions/2331316/what-is-stack-unwinding
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr155.htm
http://ootips.org/yonat/4dev/smart-pointers.html
http://www.boost.org/doc/libs/1_45_0/libs/smart_ptr/smart_ptr.htm

0

super bardzo Ci dziękuję za tak obszerną odpowiedź zaraz siadam do lektury;]
Pozdrawiam Ghost

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