Sign in to follow this  
The_Apocalypse

Function Pointers in Classes

Recommended Posts

The_Apocalypse    122
Hi everybody, I just want to add a function pointer to a class of mine that points to a function in that class.
typedef void (__thiscall* MyFuncType)(void);
class CObject
{
public:
  MyFuncType MyFunc;

  // variables
  ...

  // constructor/destructor
  CObject()
  {
    ...

    MyFunc = (MyFuncType)&CObject::TheFunction; // i tried MyFunc = (MyFuncType)TheFunction; same result!
  }
  ~CObject() {}

  // functions
  void TheFunction(void);
};
but it keeps giving me the following error: "cannot convert from 'void (__thiscall CObject::*)(void)' to void (__thiscall *)(void)'" so i changed the typedef as follows: typedef void (__thiscall CObject::*MyFuncType)(void); now it works in the constructor, but when i try to use MyFunc, i get the following error: "term does not evaluate to a function taking 0 arguments" (this didn't happen when the typedef was like in the first place, but in that way i couldn't set the function pointer to point at my function!) Please help, I'm really stuck! [depressed] BTW: I use Visual Studio 2005 BTW2: i can't use my computer with the compiler (i use my laptop now) for at least four days, so i can't test your solutions to see if they work... but any suggestions are welcome... please...[crying]

Share this post


Link to post
Share on other sites
Skizz    794
There are two ways to implement function pointers in C++. The first is the C style function pointer. To use this method, the member function in the class needs to be declared as static and the implementation of the function cannot access non-static members/methods within the class. The second (and new in C++) is to use member function pointers. To call a function via a member function pointer, you need an instance of the class to call the function with (it will become the this pointer in the function).

If you can detail the way the function pointer is to be used then someone can suggest which method to use.

Skizz

Share this post


Link to post
Share on other sites
BlodBath    150
As mentioned, it depends on how you intend to use the function pointer. If you can spare it, just make it a static function and use C style function pointers (which is actually how you have it declared there). Otherwise, you might want to look into a lightweight functor class to wrap up the class instance with the function pointer. I wrote a simple functor for a one parameter function a while back:


#ifndef EVENT_H
#define EVENT_H

// T is object type, U is the parameter type
template <class T, class U>
class Event {
public:
Event(T* objPtr, void (T::*fPtr) (const U)) {_objPtr = objPtr; _fPtr = fPtr;};
void operator()(const U param) {(*_objPtr.*_fPtr)(param);}
void Call(const U param) {(*_objPtr.*_fPtr)(param);}

private:
T* _objPtr;
void(T::*_fPtr)(const U);
};

#endif

Share this post


Link to post
Share on other sites
Fruny    1658
struct Foo;

typedef void (Foo::*func_type)();

struct Foo
{
func_type func;

void bar();
Foo();
};

Foo::Foo() : func(&Foo::bar) {}
void bar() {}

int main()
{
Foo f;

(f.*(f.func))();
}

Share this post


Link to post
Share on other sites
The_Apocalypse    122
I'm trying to use the function in a function of a Class. (so I can't declare it static, because it depends on instances)

void CObject::SomeFunction()
{
// do some stuff
...

MyFunc(); // it gives me 'term does not evaluate to a function taking 0 arguments'
}



thanks though!

EDIT: i just realized from your source codes that (MAYBE) i must place an asterisk before the function name when I call it? something like: *MyFunc(); ?

Share this post


Link to post
Share on other sites
Fruny    1658
That's because MyFunc is not a function pointer. It's a member function pointer. They are not used the same way.

FunctionPointer();

(Object.*MemberFunctionPointer)();

(ObjectPointer->*MemberFunctionPointer)();

Share this post


Link to post
Share on other sites
The_Apocalypse    122
Another question,

can I set up my function pointer in a 'child' class to point to a function in this 'child' class?

class CObject2 : public CObject
{
CObject2()
{
MyFunc = (MyFuncType)&CObject2::SomeFunction;
}
~CObject2() {}

void SomeFunction();
};



does it work? or it will give me an error that MyFunc is of type void (__thiscall CObject::*)(void) instead of void (__thiscall CObject2::*)(void)? if yes, how can this be solved? (i mean: if you have a CObject instance (obj), the function that calls MyFunc will call obj.TheFunction, but if you have a CObject2 instance (obj2), the same function that calls MyFunc (defined in CObject, not CObject2) will call obj2.SomeFunction)

thanks

EDIT: here's a complete example if you don't understand:

cobject.h
typedef void (__thiscall* MyFuncType)(void);
class CObject
{
public:
MyFuncType MyFunc;

// constructor/destructor
CObject()
{
MyFunc = (MyFuncType)&CObject::TheFunction;
}
~CObject() {}

// functions
void CallingFunction(void);
void TheFunction(void);
};

class CObject2 : public CObject
{
public:
CObject2()
{
MyFunc = (MyFuncType)&CObject2::SomeFunction;
}
~CObject2() {}

void SomeFunction(void);
};


cobject.cpp
void CObject::CallingFunction(void)
{
*MyFunc();
}

void CObject::TheFunction(void) {}

void CObject2::SomeFunction(void) {}


main.cpp
void main()
{
CObject obj;
CObject2 obj2;
obj.CallingFunction(); // I want this to call obj.TheFunction
obj2.CallingFunction(); // and this obj2.SomeFunction
}


EDIT2: I just saw your reply... thanks for the tip, but I really don't know how to use boost. (I'll learn soon, though!). anyway, thanks!!![smile]

Share this post


Link to post
Share on other sites
Fruny    1658
Quote:
Original post by The_Apocalypse
can I set up my function pointer in a 'child' class to point to a function in this 'child' class?


No. Only the other way around.

You can set a Derived::* to point to a base class member, but not a Base::* point to a derived class member. Otherwise, it would allow you to do this:

struct Foo
{
int i;
};

struct Bar
{
int j;
};

int Foo::*ptr = &Bar::j; // illegal, can't convert int Bar::* to int Foo::*
Foo f;
(f.*ptr) = 42; // oops! f doesn't have a j member.


It is the opposite from the 'usual' polymorphism rules.

Boost does indeed make a lot of your troubles go away :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this