Jump to content


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


10 replies to this topic

#1 Josh1billion

    Member

  • Members
  • PipPip
  • 76 posts

Posted 29 April 2006 - 04:00 AM

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?
Website :: Blog

Latest game release: Super Orbulite World
Current project: Stealth Prankster 2

#2 Reedbeta

    DevMaster Staff

  • Administrators
  • 5308 posts
  • LocationSanta Clara, CA

Posted 29 April 2006 - 04:47 AM

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.
reedbeta.com - developer blog, OpenGL demos, and other projects

#3 Josh1billion

    Member

  • Members
  • PipPip
  • 76 posts

Posted 29 April 2006 - 02:44 PM

I see.. thanks. That'll work, though it's a bit of a hassle.
Website :: Blog

Latest game release: Super Orbulite World
Current project: Stealth Prankster 2

#4 Josh1billion

    Member

  • Members
  • PipPip
  • 76 posts

Posted 29 April 2006 - 06:22 PM

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];

Website :: Blog

Latest game release: Super Orbulite World
Current project: Stealth Prankster 2

#5 Reedbeta

    DevMaster Staff

  • Administrators
  • 5308 posts
  • LocationSanta Clara, CA

Posted 29 April 2006 - 06:48 PM

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);

reedbeta.com - developer blog, OpenGL demos, and other projects

#6 bubu-LV-

    New Member

  • Members
  • Pip
  • 9 posts

Posted 29 April 2006 - 07:03 PM

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.

#7 Josh1billion

    Member

  • Members
  • PipPip
  • 76 posts

Posted 29 April 2006 - 07:53 PM

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

Latest game release: Super Orbulite World
Current project: Stealth Prankster 2

#8 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 29 April 2006 - 10:12 PM

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*);
};

C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#9 Reedbeta

    DevMaster Staff

  • Administrators
  • 5308 posts
  • LocationSanta Clara, CA

Posted 29 April 2006 - 10:15 PM

bubu[LV],

I thought about doing that - but you then have to use the pointer-to-member syntax which is rather ugly.
reedbeta.com - developer blog, OpenGL demos, and other projects

#10 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 03 May 2006 - 01:13 PM

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)


monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*

#11 AndyP

    New Member

  • Members
  • PipPip
  • 15 posts

Posted 03 May 2006 - 03:26 PM

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





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users