Funktionspekare.

Allting som har med programmering att göra.

Funktionspekare.

Inläggav TheSpaceMan » 03 sep 2009, 21:18

Det är en sak jag varit med om hela livet, det är att när någon nämner funktionspekare börjar alla darra, ser lite lätt skräckslagna ut innan dom börjar göra något annat.

Jag erkänner att jag inte är bevandrad i området och nu när jag leker ser det oftast ut så här t ex.

  1.     void addChild(Node* node, void* sortFunc)
  2.     {
  3.         // OH MY GOD! Magic function pointer!!!
  4.         bool (*sortFunction) (Node*);          
  5.         sortFunction = (bool(__cdecl *)(Node*))sortFunc; // <- This one
  6.  
  7.         bool sortLeft = sortFunction(node);
  8.                   [...]
  9.  


Finns det något finnare sätt att göra följande cast på?
Kanske som är säkrare etc?

Folk säger oftast att jag ska användas boost funktioner som är säkrare, och där kan jag väl hålla med, men ibland kan det vara bra att veta vad saker är grundande på och hur det kan skötas.
TheSpaceMan
 
Inlägg: 102
Blev medlem: 11 maj 2009, 23:31
Ort: Nottingham

Re: Funktionspekare.

Inläggav sirGustav » 03 sep 2009, 22:43

  1. typedef bool (__cdecl *func)(Node*);
  2. func f = reinterpret_cast<func>(sortFunc);

kanske fungerar, det var ett tag sedan jag castade i C++, fast säkrare vete tusan om det är. Du vill casta från en void* till en funktions* och då är typsäkerhet och andra trevligheter redan utslänga genom fönstret för länge sedan...
och ja... boost.function eller en functor är bättre :)
sirGustav
 
Inlägg: 45
Blev medlem: 06 jun 2009, 14:46
Ort: Malmö

Re: Funktionspekare.

Inläggav dooz » 04 sep 2009, 08:03

En bra, om än rätt tung, beskrivning av hur man kan skriva typsäkra funktionspekare i C++ (med godtyckligt antal parametrar) finns i Alexandrescus Modern C++ Design. Det tog mig ett bra tag att haja hur det funkade, och sen insåg jag att det var sån kod som jag nog inte ville skriva själv (i något generellt fall), utan använder glatt boost::bind/boost::function istället.

Jag babblade lite om det i en tidigare blog post, ser jag :)

Edit. Hrm, jag undrar om inte den här artikeln på Dr Dobb är rätt vettig.
Användarvisningsbild
dooz
 
Inlägg: 37
Blev medlem: 11 maj 2009, 21:04
Ort: Göteborg

Re: Funktionspekare.

Inläggav Hildenborg » 05 sep 2009, 09:28

Själv tycker jag att man bör vara försiktig i användandet av funktionspekare. Speciellt när man kan göra snyggare lösningar med hjälp av C++ och virtuella metoder.
I de sällsynta fallen då användandet av funktionspekare är bästa alternativet, så skriver jag bara syntaxen rakt upp och ned. I det läget så kan den "krångliga" syntaxen vara till en fördel, då andra programmerare som använder sig av det hela måste skärpa till sig och tänka på vad dom gör.
Fast det är bara min syn på saken, och inte något råd för hur man bör göra :)
Sun Tzu: "In peace prepare for war, in war prepare for peace."
Användarvisningsbild
Hildenborg
Site Admin
 
Inlägg: 191
Blev medlem: 22 apr 2009, 20:25
Ort: Göteborg

Re: Funktionspekare.

Inläggav TheSpaceMan » 05 sep 2009, 11:29

Yes. Jag håller ju med folk om att man ska vara försiktig med funktionspekare det gäller ju också pekare i övrigt och mycket.

En del av dom grejer som jag har lekt det med är blanda annat:

Create anropet för olika objekt i en object manager.
Create funktionen tar ett TiXmlElment* och retunerar ett grundläggande *Object. Objekten registeras in i en manager och sorteras enligt olika flagor. Där ville jag inte skriva unik create kod och ändra i objekt managern varje gång jag la till en ny objekt typ i motorn (då varje typ hade behövt newa fram ett nytt objekt av sin typ.) Jag skapa en C-style funktioner som levde i samma header cpp som det nya objektet, den create funktionen ansvarade för att retunera en ny av sin typ och gjorde det som var unikt för den objekttypen. Sedan användes en registerCreate funktion, som tog en std string och en void*, sedan kunde jag vid skaptillfället genom att bara se <tag> namn på objektet, veta vilken create funktion jag var ute efter och nyttja den.

Olika sort funktioner:
Ja den såg ni ju, och den var ju grunden för den här, att när man stoppar in en nod (i detta fall) i ett binärt träd kunna lätt ändra kriterie för hur det sorterar.

Inget avancerat och saker som antaligen lätt går att lösa på andra sätt.

Create funktionen för varje object hade kunnat lösa med en singleton skapare för den unika typen.
TheSpaceMan
 
Inlägg: 102
Blev medlem: 11 maj 2009, 23:31
Ort: Nottingham

Re: Funktionspekare.

Inläggav sirGustav » 05 sep 2009, 18:06

Skaparen hade jag tidigare låtit vara en funktionspekare, men som jag nu låter vara en sub-klass till ObjectType, eftersom jag oftast ger de mer funktionalitet än bara skapandet, exempelvis förstörandet av objektet och dess namn..

När jag tänker efter det så hade jag nog låtit sorteringsfunktionen vara en templateparameter eftersom det är troligtvis bestämt i förväg hur du vill sortera. Du slipper dessutom bry dig om vad som händer om man bytar sorteringsmetod mitt i och din cache blir gladare :)
sirGustav
 
Inlägg: 45
Blev medlem: 06 jun 2009, 14:46
Ort: Malmö


Återgå till Programmering

Vilka är online

Användare som besöker denna kategori: Inga registrerade användare och 0 gäster

cron