4

I'm having trouble making a function pointer to a class method. I made a function pointer to a non-class method and it works fine.

int foo(){
    return 5;
}

 int main()
{
    int (*pointer)() = foo;

    std::cout << pointer();

    return 0;
}

I tried to apply this to have an instance variable in a class be a function pointer.

This is the header file. It declares the private method Print which the variable method will point to.

class Game
{

public:

    Game();

private:

    void Print();

    void (method)( void );

};

The Game constructor attempts to assign the pointer method to the address of the Print method. Upon compile, an error comes up at that line saying "error: reference to non-static member function must be called;". I don't know what that means. Whats the correct way of implementing this?

Game::Game( void )
{

    method = &Game::Print;

}

void Game::Print(){
    std::cout << "PRINT";
}
Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
j76goatboy
  • 405
  • 2
  • 7
  • 16
  • You need `void (Game::*method)();` if you want to use a member function of the `Game` class that returns nothing and has no parameters. – James Adkison May 01 '16 at 17:16

3 Answers3

8

A member function is quite a bit different from an ordinary function, so when you want to point to a member function you need a pointer-to-member-function, not a mere pointer-to-function. The syntax for a pointer-to-member-function includes the class that the member function is a member of:

void (Game::*mptr)();

This defines a pointer-to-member-function named mptr that holds a pointer to a member function of the class Games that takes no arguments and returns nothing. Contrast that with an ordinary function pointer:

void (*ptr)();

This defined a pointer-to-function named ptr that holds a pointer to a function that takes no arguments and returns nothing.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • 1
    That works. The only way I could find to call method is `(this->*method)();` Is there a nicer way to call it? I also don't see what the difference is between that and `(*method)();` – j76goatboy May 01 '16 at 19:30
  • The difference is that a (non-static) member function has to be called on an object. That's what `this->*` does. – Pete Becker May 01 '16 at 19:59
  • Thanks, @j76goatboy, the parenthesis around the this->*method is what I was missing. For others who might be running into the same issue, without the parenthesis you'll get `error: called object type 'void (ClassNameHere::*)()' is not a function or function pointer` with clang++. – David Vereb Aug 07 '23 at 13:47
5

Just found out you can do

#include <functional>
#include <cassert>

using namespace std;

struct Foo {
   int x;
   int foo() { return x; }
};

int main() {
  function<int(Foo&)> f = &Foo::foo;
  Foo foo = { 3 };
  assert(f(foo) == 3);
  foo.x = 5;
  assert(f(foo) == 5);
}

std::mem_fn() might work too: https://en.cppreference.com/w/cpp/utility/functional/mem_fn

solstice333
  • 3,399
  • 1
  • 31
  • 28
0

1- Use the following syntax to point to a member function:

return_type (class_name::*ptr_name) (argument_type) = &class_name::function_name;

2- keep in mind to have a pointer to member function you need to make it public.

in your case:

class Game
{

public:

    Game(){}

    void print() { 
      //todo ...
    }


};
// Declaration and assignment
void (Game::*method_ptr) () = &Game::print;