C++ - possible to define an array of function pointers?

25a03a09475cc50dc4b724289232233a
0
Josh1billion 101 Apr 29, 2006 at 04:00

I want to have an array of function pointers called “ticks”, declared below:

void (*ticks[30])();

That works fine– compiles without any problems.

Now, I’m wondering if it’d be possible to individually code all of those (see psuedo-code below), or would I have to code functions and then point the pointers of the array to those functions? That’d be a bit of a hassle.

Psuedo-code of how I want to do this:

void (*ticks[0])()
{
  // do something
}

void (*ticks[1])()
{
  // do something else
}

etc.

Is that possible? If not, is there an efficient alternative?

10 Replies

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Apr 29, 2006 at 04:47

You can’t declare a function with the syntax in the second code box. That doesn’t work for single function pointers, much less arrays of function pointers.

However, you can initialize the array by doing something like:

void (*ticks[30])() = { &tick0, &tick1, &tick2, /* etc */ &tick29 };

where tick0…tick29 are previously declared functions.

25a03a09475cc50dc4b724289232233a
0
Josh1billion 101 Apr 29, 2006 at 14:44

I see.. thanks. That’ll work, though it’s a bit of a hassle.

25a03a09475cc50dc4b724289232233a
0
Josh1billion 101 Apr 29, 2006 at 18:22

New question..

I did as you said, now, I need to allow those functions to access members of an NPCObject class. NPCObject has a function pointer that will point to one of the functions pointed to by the pointers in the array.

Hard to explain, so let me show you the code I’m talking about…

// First, we have the code of the functions themselves...
void ticks0()
{
    // here, I want to have some code that accesses NPCObject's members (is this possible?).  NPCObject will have a function pointer pointing to this function.
}

void ticks1()
{

}

// etc...

// and the array:

void (*ticks[30])() = { &ticks0, &ticks1, &ticks2, &ticks3, &ticks4, &ticks5, &ticks6, &ticks7, &ticks8,
                       &ticks9, &ticks10, &ticks11, &ticks12, &ticks13, &ticks14, &ticks15, &ticks16, &ticks17,
                       &ticks18, &ticks19, &ticks20, &ticks21, &ticks22, &ticks23, &ticks24, &ticks25, &ticks26,
                       &ticks27, &ticks28, &ticks29 };

class NPCObject
{   
public: 
    void (*action)(); // "script" pointer.. function called when the player "talks" to the NPC
    void (*tick)(); // "script" pointer.. function to be called each frame
    

};

Then, in one of NPCObject’s functions:

tick = ticks[tick_id];
action = actions[action_id];
A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Apr 29, 2006 at 18:48

One way would be to just make the members of NPCObject public, or make each of the tick functions friends of NPCObject, and pass a pointer to ‘this’ to each tick function:

void (*ticks[30])(NPCObject *) = { /* blah */ };
// in NPCObject
tick(this);
2a316b135fe9b24a09f153f6b9ee413a
0
bubu_LV_ 101 Apr 29, 2006 at 19:03

Your tick functions must be in class to be used your way.

class NPCObject
{   
public: 
    void (*action)(); // "script" pointer.. function called when the player "talks" to the NPC
    void (*tick)(); // "script" pointer.. function to be called each frame

    void ticks1(); 
    void ticks2();
    // ...
};

If you don’t need class private data in these ticksX functions then declare them static (also action and tick fuction pointer too).

Another thing to think about - maybe virtual functions can make better code.

25a03a09475cc50dc4b724289232233a
0
Josh1billion 101 Apr 29, 2006 at 19:53

I’ve decided to use Reedbeta’s idea here. Shortly after posting my previous reply, I thought about doing something similar.. this is good.

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Apr 29, 2006 at 22:12

If you truly want to shield your datamembers from others while leaving them accessible for your tick functions, you can define the members in a dataclass from which NPCObject privately inherits (or use this class as a private datamember for NPCObject, I actually think this is a better solution although it breaks current code). Then, pass along a pointer to that data when you call the tick functions.

As the NPCObject is the only class that can access the data, it’s his responsibility to pass the pointer to the tick function, so you should probably wrap the tick() call in NPCObject.

Somethink like this:

struct NPCObjectData
{
    int foo, bar;
};

class NPCObject : private NPCObjectData
{
public:
    void tick()
    {
        tickptr(this);
    }

    void action()
    {
        actionptr(this);
    }

private:
    void (*tickptr)(NPCObjectData*);
    void (*actionptr)(NPCObjectData*);
};
A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Apr 29, 2006 at 22:15

bubu[LV],

I thought about doing that - but you then have to use the pointer-to-member syntax which is rather ugly.

6f0a333c785da81d479a0f58c2ccb203
0
monjardin 102 May 03, 2006 at 13:13

You could use boost::function to clean up the syntax:

boost::function<int (int)> f;
X x;
f = std::bind1st(
      std::mem_fun(&X::foo), &x);
f(5); // Call x.foo(5)
77f6fa16a7321f737bd264ee000aa91b
0
AndyP 101 May 03, 2006 at 15:26

if you don’t mind using disgusting macros and global variables (note: I do), you could do this:

typedef void (* TickFnc)( );
struct TickList
{
    TickFnc m_Ticks[ 30 ];
    int m_NumTicks;

    TickList( ) : m_NumTicks( 0 ) { }
};

struct AddToTickList
{
    AddToTickList( TickList& ticks,TickFnc fnc )
    {
         ticks.m_Ticks[ ticks.m_NumTicks++ ] = fnc;
    }
};

extern TickList g_Ticks;

#define MAKE_TICK_FNC( Name ) \
    extern void Name( ); \
    AddToTickList g_AdderFor##Name##( g_Ticks, Name ); \
    void Name( )

Now you can define your tick functions like this (in cpp files only, not in headers):

MAKE_TICK_FNC( MyTickFnc1 )
{
   // code here
}
MAKE_TICK_FNC( MyTickFnc2 )
{
   // code here
}

Pointers to MyTickFnc1 and MyTickFnc2 will be automagically stored in g_Ticks.m_Ticks[0] and g_Ticks.m_Ticks[1] respectively.
Health warning: Macros make you go blind