[an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] (none) [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] (none) [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive]
 
[an error occurred while processing this directive] [an error occurred while processing this directive]
Skåne Sjælland Linux User Group - http://www.sslug.dk Home   Subscribe   Mail Archive   Forum   Calendar   Search
MhonArc Date: [Date Prev] [Date Index] [Date Next]   Thread: [Date Prev] [Thread Index] [Date Next]   MhonArc
 

Re: [CPROG] ANSI C++ og events



"Peter Aagaard Kristensen" <sslug@sslug> writes:

> Det er en mulighed, men desværre har jeg ingen forudsætninger om
> hvilken klasse det er der skal bruge eventsne. Det er selvfølgelig
> muligt at lave en baseclass for hver eventtype og så pålægge
> brugeren at han skal nedarve fra den klasse for at kunne "binde"
> funktionen sammen med eventet, men det bliver nok noget rodet og
> også alt for meget arbejde for alt for lidt - så det ville jeg helst
> undgå hvis det var muligt.

Tja, du kunne lave en slags adapter. Altså dine callbacks bruger en
klasse som ser sådan ud (et eksempel der compiler med g++ 2.95 :) )

#include <stdio.h>

// Abstract functor - function object
class Functor {
public:
    virtual void execute(void *data) = 0;
    virtual ~Functor() { }
};

// A function object which will call a method in a class
template <class C> class ClassFunctor : public Functor{
    typedef void (C::*ExecuteFun) (void*);
public:
    ClassFunctor(ExecuteFun function, C& klass) : 
	itsFunction(function), itsClass(klass) { }
private:
    C& itsClass; 
    ExecuteFun itsFunction;

    virtual void execute(void *data) { (itsClass.*itsFunction)(data); }
};

// A test class which we want to call back
class TestClass {
public:
    void calledBack(void*) { printf("I was called back!\n"); }
};

// somewhere else, all we have is the functor
void elsewhere(Functor& functor) {
    functor.execute(NULL);
}
    

int main() {
    TestClass test;
    // make a functor that can call methods in TestClasses
    ClassFunctor<TestClass> functor (&TestClass::calledBack, test);

    // Pass it to this function which doesn't know anything about TestClass
    elsewhere(functor);
    return 0;
}


Det er vist en rimelig klassisk opstilling. Jeg har ikke lige nogle
seriøse C++ bøger ved hånden, så jeg kan ikke lige foreslå noget der
beskriver det nærmere.

libgsigc++ er måske lidt overkill, men den udvider på ovenstående. Fx
kan du i ovenstående kun overføre en void* som parameter -- hvis du
vil også have en værdi tilbage, overføre flere parametere osv. bliver
det lidt mere kompliceret.


[Jeg foretrækker selv sprog som Python hvor man ikke behøver skrive 100
liniers kode for at kalde en funktion ;) ]

#!/usr/bin/python
class TestClass:
  def calledBack(self,param): print "I was called back with %s" % param

test = TestClass()         # instantiate TestClass
callBack = test.calledBack # Get a method "pointer"
callBack('en parameter')   # Call the right method in the right object


PS: Jeg kopierede noget gammelt kode jeg selv har skrevet over i
eksemplet, men jeg kommer i tanke om at man typisk bruger overloadet
operator() i stedet for execute -- så for at kalde functor'en siger
man bare functor(NULL).

Her er lidt mere info: http://www.newty.de/links.html#fpt


-- 
===============================================================
<sslug@sslug>     Herlev, Denmark     Software Designer
<URL:http://www.andreasen.org/>   <*>   Eicon Networks Research
===============================================================



 
Home   Subscribe   Mail Archive   Index   Calendar   Search

 
 
Questions about the web-pages to <www_admin>. Last modified 2005-08-10, 20:08 CEST [an error occurred while processing this directive]
This page is maintained by [an error occurred while processing this directive]MHonArc [an error occurred while processing this directive] # [an error occurred while processing this directive] *