Newsgroup: it.comp.lang.c++
Titolo: Puntatori a funzioni membro e classi derivate

Il codice seguente è corretto?
#include <iostream>
struct Base;
typedef void (Base::* METHOD)();
struct Base{
    void call(METHOD func){
        (this->*func)();
    }
    void foo(){
        std::cout << "Base" << std::endl;
    }
};
struct Der : public Base{
    void bar(){
        std::cout << "Der" << std::endl;
    }
};
int main(){
    Der * d = new Der();
    d->call(&Base::foo);
    d->call((METHOD)&Der::bar);                   <== !!!
    return 0;
}
Il cast è undefined behavior, vero? Se sì c'è un modo per ottenere qualcosa 
di simile in maniera corretta? Mi sembra che wxWindows (una libreria per 
GUI) usi questo metodo per gestire gli eventi, quindi, anche se è 
undefined, penso sia supportato dalla maggior parte dei compilatori, o 
sbaglio?
-- 
Marco Barisione
http://spazioinwind.libero.it/marcobari/

 Il codice seguente è corretto?
Scusa, non sono sicuro di aver compreso bene il problema ma così
modificato ti andrebbe bene?
#include <iostream>
struct Base;
struct Der;
typedef void (Base::* METHODB)();
typedef void (Der::* METHODD)();
struct Base{
    void call(METHODB func){
        (this->*func)();
    }
    void foo(){
        std::cout << "Base" << std::endl;
    }
};
struct Der : public Base{
    void call(METHODD func){
        (this->*func)();
    }
    void bar(){
        std::cout << "Der" << std::endl;
    }
};
int main(){
    Der * d = new Der();
    d->call(&Base::foo);
    d->call(&Der::bar);
    return 0;
}
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg

 };
Ridefinire call non è accettabile.
Sto scirvendo un leggerissimo strato di rivestimento intorno alle API di 
Windows per realizzare una GUI in modo semplice senza dovermi portare 
dietro il peso di MFC, wxWindows, QT o simili.
Ho bisogno di un sistema comodo per legare degli eventi a dei metodi, ad 
esempio se ho una classe Frame definita dalla libreria vorrei poter fare:
class MioFrame : Frame{
public:
    MioFrame(...) : Frame(...){
        link("destroy", this, (METHOD)OnDestroy);
    }
    void OnDestroy(){
        ...
    }
};
Quindi quando avviene l'evento chiamato "destroy" viene richiamato il 
metodo OnDestroy.
Ovviamente non è possibile ridefinire ogni volta link in modo che funzoni 
correttamente.


"Marco Barisione" ha scritto
: Il codice seguente è corretto?

:
Il cast non e` undefined behaviour. Si puo' fare, salvo che il risultato
e` specificato solo se lo ricasti nel tipo di partenza. In quel caso
ottieni esattamente il puntatore iniziale.
Comunque si puo` sempre fare qualcosa di simile a:
#include <iostream>
struct Base; typedef void (*method_t)(Base*);
struct Base {
    void call(method_t func) {
        func(this);}
    friend void foo(Base* self) {
        std::cout << "Base" << std::endl;}};
struct Der : Base {
    friend void bar(Base *self) {
        std::cout << "Der" << std::endl;}};
int main() {
    Der * d = new Der();
    d->call(foo);
    d->call(bar);}
Lo trovo molto elegante.
Massimo

         std::cout << "Der" << std::endl;}};
Non sapevo che potesse funzionare. Non mi piace molto avere l'argomento 
self esplicito in C++.
