Build Your Own Arcade Controls Forum

Main => Software Forum => Topic started by: Buddabing on September 19, 2006, 10:14:13 am

Title: Help requested: C++ member function pointers
Post by: Buddabing on September 19, 2006, 10:14:13 am
Hello,

The following code gives me a compiler error: "Cannot convert int(ExampleClass::*)() to int(*)() in assignment:

Code: [Select]
#include <stdio.h>

class ExampleClass
{
   public:
   int (*member)(void);
   int foo(void)
   {
      return 1;
   }
   int bar(void)
   {
      return 2;
   }
   void SetFoo(void)
   {
      member=&ExampleClass::foo; // <----------------error here
   }
   void SetBar(void)
   {
      member=&ExampleClass::bar; // <----------------error here
   }
   int CallMember(void)
   {
      return (*member)();
   }
}

main(int argc, char **argv)
{
   ExampleClass ex;
   int result;

   ex.SetFoo();
   printf("result from SetFoo=%d\n",ex.CallMember());
   ex.SetBar();
   printf("result from SetBar=%d\n",ex.CallMember());
   return 0;
}


Any help correcting the syntax would be appreciated.

TIA,
Buddabing
Title: Re: Help requested: C++ member function pointers
Post by: Spartan on September 19, 2006, 10:42:33 am
Make foo and bar static, and pass in the instance of 'ex' as an argument.
Title: Re: Help requested: C++ member function pointers
Post by: youki on September 19, 2006, 10:46:36 am
class ExampleClass
{
   public:
   int (*member)(void);
   static int foo(void)
   {
      return 1;
   }
   static int bar(void)
   {
      return 2;
   }
   void SetFoo(void)
   {
      member=&ExampleClass::foo;
   }
   void SetBar(void)
   {
      member=(&ExampleClass::bar);
   }
   int CallMember(void)
   {
      return (*member)();
   }
};


It compiles under VC++
Title: Re: Help requested: C++ member function pointers
Post by: MustardTent on September 19, 2006, 10:51:58 am
The reason "static" needed is because member function pointers cannot be dereferenced without an associated object.   For each member function a "this" pointer is passed implicitly, even though it is not in the function prototype.

Check out this (http://linuxquality.sunsite.dk/articles/memberpointers/) for a little more info.
Title: Re: Help requested: C++ member function pointers
Post by: Buddabing on September 19, 2006, 11:33:18 am
That worked, but I need to be able to access other members of the class from within the static function:

Code: [Select]
#include <stdio.h>

class ExampleClass
{
   public:
   int (*member_fn)(void);
   int member_int;
   static int foo(void);
   static int bar(void);
   void SetFoo(void);
   void SetBar(void);
   int CallMember(void);
};

int ExampleClass::foo(void)
{
   member_int=1; //<---------------error
   return 1;
}

int ExampleClass::bar(void)
{
   member_int=2; //<---------------error
   return 2;
}

void ExampleClass::SetFoo(void)
{
   member_fn=&ExampleClass::foo;
}

void ExampleClass::SetBar(void)
{
   member_fn=&ExampleClass::bar;
}

int ExampleClass::CallMember(void)
{
   return (*member_fn)();
}

main(int argc, char **argv)
{
   ExampleClass ex;
   int result;

   ex.SetFoo();
   printf("result from SetFoo=%d, member_int=%d\n",
      ex.CallMember(),ex.member_int);
   ex.SetBar();
   printf("result from SetBar=%d, member_int=%d\n",
      ex.CallMember(),ex.member_int);
   return 0;
}

The error when this is compiled is "Invalid use of member 'ExampleClass::member_int' in static member function".
Title: Re: Help requested: C++ member function pointers
Post by: youki on September 19, 2006, 11:41:02 am
declare the member as static :

static int member_int;
Title: Re: Help requested: C++ member function pointers
Post by: screaming on September 19, 2006, 11:43:09 am
member_int isn't declared static, so accessing it without instantiating ExampleClass won't work.
Title: Re: Help requested: C++ member function pointers
Post by: screaming on September 19, 2006, 11:45:24 am
Out of curiosity, why are you doing this?

Code: [Select]
void SetFoo(void)
   {
      member=&ExampleClass::foo; // <----------------error here
   }

  Since this is the part that's causing you all this headache, are you sure there's no other way to do it?
Title: Re: Help requested: C++ member function pointers
Post by: max8061 on September 19, 2006, 11:49:18 am
Out of curiosity, why are you doing this?

Free homework help on BYOAC?  :laugh2:
Title: Re: Help requested: C++ member function pointers
Post by: Buddabing on September 19, 2006, 11:57:17 am
Declaring member_int as static gives me linkage errors: "undefined reference to ExampleClass::member_int".

There are always alternate ways of doing this kind of thing. I could make member_int a global variable, or a static external to the class, or I could use a construct such as:

enum
{
   FOO,
   BAR
};

switch (state)
{
   case FOO:
      return foo();
   break;
   case BAR:
      return bar();
   break;
}

But that's not very elegant.

It is not strictly necessary to use the function pointers like I am doing. But that's what I want to do.
Title: Re: Help requested: C++ member function pointers
Post by: Spartan on September 19, 2006, 12:29:45 pm
See my first reply -- make the member functions static, then pass in the ex as an argument....
Title: Re: Help requested: C++ member function pointers
Post by: screaming on September 19, 2006, 12:34:56 pm
What if you have 2 classes?

Code: [Select]
#include <stdio.h>

// CLASS: ExampleFuncs
class ExampleFuncs
{
    public:
    static int foo(void);
    static int bar(void);
};

int ExampleFuncs::foo(void)
{
  return 1;
}

int ExampleFuncs::bar(void)
{
   return 2;
}


class ExampleClass
{
   public:
   int (*member_fn)(void);
   int member_int;
   int foo(void);
   int bar(void);
   void SetFoo(void);
   void SetBar(void);
   int CallMember(void);
};

void ExampleClass::SetFoo(void)
{
   member_int=ExampleFuncs::foo();
   member_fn = &ExampleFuncs::foo;
}

void ExampleClass::SetBar(void)
{
   member_int=ExampleFuncs::bar();
   member_fn=&ExampleFuncs::bar;
}

int ExampleClass::CallMember(void)
{
   return (*member_fn)();
}

main(int argc, char **argv)
{
   ExampleClass ex;
   int result;

   ex.SetFoo();
   printf("result from SetFoo=%d, member_int=%d\n",
      ex.CallMember(),ex.member_int);
   ex.SetBar();
   printf("result from SetBar=%d, member_int=%d\n",
      ex.CallMember(),ex.member_int);
   return 0;
}

It compiles on Linux.....

steveb@freda ~/budda $ gcc -lstdc++ -o test main.cpp
steveb@freda ~/budda $ ./test
result from SetFoo=1, member_int=1
result from SetBar=2, member_int=2
steveb@freda ~/budda $

Title: Re: Help requested: C++ member function pointers
Post by: Buddabing on September 19, 2006, 12:41:18 pm
That won't work because foo() and bar() need to access member_int directly.
Title: Re: Help requested: C++ member function pointers
Post by: Spartan on September 19, 2006, 01:01:58 pm
I keep telling you -- pass in ex as an argument!

Code: [Select]
#include <stdio.h>

class ExampleClass
{
   public:
   int (*member)(ExampleClass e);
   static int foo(ExampleClass e)
   {
      return 1;
   }
   static int bar(ExampleClass e)
   {
      return 2;
   }
   void SetFoo(void)
   {
      member=&ExampleClass::foo; // <----------------error here
   }
   void SetBar(void)
   {
      member=&ExampleClass::bar; // <----------------error here
   }
   int CallMember(ExampleClass e)
   {
      return (*member)(e);
   }
};

int main(int argc, char **argv)
{
   ExampleClass ex;
   int result;

   ex.SetFoo();
   printf("result from SetFoo=%d\n",ex.CallMember(ex));
   ex.SetBar();
   printf("result from SetBar=%d\n",ex.CallMember(ex));
   return 0;
}
Title: Re: Help requested: C++ member function pointers
Post by: Buddabing on September 19, 2006, 01:56:56 pm
Okay, this works, like Spartan said, pass a pointer to the class as a parameter to any function which can be assigned to a function pointer, then members of the class can be accessed from the statically declared members.

Code: [Select]

#include <stdio.h>

class ExampleClass
{
   public:
   int (*member_fn)(ExampleClass *);
   int member_int;
   static int foo(ExampleClass *);
   static int bar(ExampleClass *);
   void SetFoo(void);
   void SetBar(void);
   int CallMember(ExampleClass *);
};

int ExampleClass::foo(ExampleClass *e)
{
   e->member_int=1;
   return 1;
}

int ExampleClass::bar(ExampleClass *e)
{
   e->member_int=2;
   return 2;
}

void ExampleClass::SetFoo(void)
{
   member_fn=&ExampleClass::foo;
}

void ExampleClass::SetBar(void)
{
   member_fn=&ExampleClass::bar;
}

int ExampleClass::CallMember(ExampleClass *e)
{
   return (*member_fn)(e);
}

main(int argc, char **argv)
{
   ExampleClass ex;
   int result;

   ex.SetFoo();
   printf("result from SetFoo=%d, member_int=%d\n",
      ex.CallMember(&ex),ex.member_int);
   ex.SetBar();
   printf("result from SetBar=%d, member_int=%d\n",
      ex.CallMember(&ex),ex.member_int);
   return 0;
}



Thanks all!
Title: Re: Help requested: C++ member function pointers
Post by: Spartan on September 19, 2006, 04:29:35 pm
You're welcome ;)
Title: Re: Help requested: C++ member function pointers
Post by: screaming on September 19, 2006, 04:49:39 pm
what was he supposed to be passing as a what?