[c++] Function pointer

Pagina: 1
Acties:
  • 133 views sinds 30-01-2008
  • Reageer

  • jos707
  • Registratie: December 2000
  • Laatst online: 13-05 15:26
Ik weet niet of ik dit goed kan uitleggen..
Ik heb twee klassen,ik roep in klasse 1 dmv een object een functie in klasse 2 op.
Nu wil ik in de functie dat ik aanroep terug een functie aanroepen in klasse 1. En
dit zonder een nieuw object aan te maken van klasse 1.

Ik heb dit geprobeerd door een function pointer te gebruiken
maar dan krijg ik deze error:
error C2276: '&' : illegal operation on bound member function expression

Een voorbeeld maakt het duidelijker.
C++:
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class CDit
{
 CDat dat;

 dat.daar(&telop);

 float telop(float a,float b)
 {
  return a+b;
 }
}


class CDat
{
 void daar(float (*ptr)(float a,float b))
 {
  float res = ptr(1.56,10);
 }
}

Het object 'dat' meegeven naar klasse 2 is geen optie voor mij.
Wat is de meest correcte manier om dit op te op te lossen?

  • ATS
  • Registratie: September 2001
  • Laatst online: 12-02 13:46

ATS

Op http://www.newty.de/fpt/index.html staat een vrij uitgebreide tutorial. Misschien kan je daarin vinden wat je zoekt?

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

telop static maken?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15-05 03:15

.oisyn

Moderator Devschuur®

Demotivational Speaker

jos707 schreef op zondag 06 februari 2005 @ 04:10:
Een voorbeeld maakt het duidelijker.
Je code klopt sowieso niet, die dat.daar(&telop) is illegaal in een klasse definitie, je kunt alleen binnen functies statements kwijt. Maar ik vermoed dat je het even uit je losse pols getikt hebt tijdens je topicstart, aangezien het niet strookt met de error die je gaf :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Daos
  • Registratie: Oktober 2004
  • Niet online
Het kan zijn dat je die & weg moet laten.

In de variabele zit het adres van die functie. Dit is vergelijkbaar met de a in de a[i].


Sommige Compilers lezen het allebei.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Zoijar heeft gelijk, telop gebruikt geen (non-static) members dus het moet een static zijn. Als telop wel members zou gebruiken, dan moet je een pointer to member function (PMF) gebruiken. De syntax wordt dan &CDit::telop en float (CDit::*ptr) (float a,float b)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • jos707
  • Registratie: December 2000
  • Laatst online: 13-05 15:26
Dit is idd uit de losse pols om het duidelijker te maken.
Nu 'telop' static maken is juit wat ik probeerde te vermijden, wat dan
kan ik in deze functie ook alleen maar static variabelen gebruiken.
En het weglaten van die & werk ook niet.

Misschien moet ik een proberen om het object mee te geven bij de aanroep
van 'daar' en dan dit object gebruiken om 'telop' terug aan te roepen.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

jos707 schreef op zondag 06 februari 2005 @ 13:44:
Dit is idd uit de losse pols om het duidelijker te maken.
Nu 'telop' static maken is juit wat ik probeerde te vermijden, wat dan
kan ik in deze functie ook alleen maar static variabelen gebruiken.
En het weglaten van die & werk ook niet.

Misschien moet ik een proberen om het object mee te geven bij de aanroep
van 'daar' en dan dit object gebruiken om 'telop' terug aan te roepen.
Je moet even goed het verschil tussen een member funtie en een non-member nakijken. Een member funtie (niet static dus) obj.foo(1,2) wordt aangeroepen als namemangling_foo(&obj, 1, 2) intern. Er wordt dus een this pointer meegegeven. Vandaar dat als je een pointer to member hebt, je ook altijd een object mee moet geven, waar het op werkt.

Ik zou persoonlijk niet snel met pointers-to-members werken. Er is meestal wel een mooier alternatief, eventueel met inheritance oid.

  • jos707
  • Registratie: December 2000
  • Laatst online: 13-05 15:26
Ok thx voor de antwoorden.
Idd echt een mooie oplossing is dit niet. Hoewel ik het nu wel
werkende heb gekregen doet dit de overzichtelijkheid van de code
geen goed. Ik ga over een andere boeg gooien, het eens
proberen met overerving.

  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
Probeer het anders eens op de manier zoals java events stuurt: met een interface (in C++-termen, een abstract base class). Dus:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class ICalc{
  public:
    virtual float telop(float a, float b) = 0;
};

class CDat{
  public:
    void useCalc(ICalc *pCalc)
      {pCalc->telop(2, 8);}
};

class CDit: public ICalc{
  CDat dat;

  public:
    float telop(float a, float b)
      {return a+b;}

    CDit(){
      dat.useCalc(this);
    }
};

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Doe dan op z'n minst ICalc&, naked pointers zijn onhandig. Bovendien wil je waarschijnlijk ook een virtual ~ICalc( ), kortom het wordt al snel ingewikkelder dan nodig.

Zelf begin ik gecharmeerd te raken van het boost::bind concept om gewoon een
CDit* (of CDit&, maakt met boost::bind niet uit) object en een CDit::* member functie als een pakketje door te geven.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
MSalters schreef op zondag 06 februari 2005 @ 17:05:
Doe dan op z'n minst ICalc&, naked pointers zijn onhandig. Bovendien wil je waarschijnlijk ook een virtual ~ICalc( ), kortom het wordt al snel ingewikkelder dan nodig.
Als je dit principe puur gebruikt voor callback-functies, waarbij useCalc() nooit eigenaar wordt van het ICalc-object (d.w.z.: useCalc() is niet verantwoordelijk voor de destructie van het ICalc-object), dan heb je ook geen virtual destructor nodig.
Imho werkt dit principe voor model-view situaties prima.
Zelf begin ik gecharmeerd te raken van het boost::bind concept om gewoon een
CDit* (of CDit&, maakt met boost::bind niet uit) object en een CDit::* member functie als een pakketje door te geven.
Ligt een beetje aan de situatie. Als je werkt met user-interface code in Model-View(-Controller)-stijl, dan heb je vaak een groep events/callback-functies waarvan je op de hoogte wil blijven; in zo'n situatie vind ik een interface dan gepaster. Gaat het om 1 enkele methode die je door wil geven, of wil je een specifieke implementatie van 1 methode doorgeven, dan is een pointer-to-member-function eleganter.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
GUI code doe ik in Qt, dus dan heb je signals/slots. Zonder Qt is boost::signals een optie, maar daar heb ik nog niet naar gekeken. Ik zie namelijk niet zo vaak callbacks bij events, dat is toch vaak een-richting verkeer, danwel twee logisch separate events (input/redraw).
Je moet niet proberen om View de redraw te laten initieren na input, dat breekt bij meerdere views, en werkt niet lekker bij input zonder docchange of docchange zonder (View) input.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1