Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function pointers to member functions

There are several duplicates of this but nobody explains why I can use a member variable to store the pointer (in FOO) but when I try it with a local variable (in the commented portion of BAR), it's illegal. Could anybody explain this?

#include <iostream>
using namespace std;

class FOO
{
public:
 int (FOO::*fptr)(int a, int b);
 int add_stuff(int a, int b)
 {
  return a+b;
 }
 void call_adder(int a, int b)
 {  
  fptr = &FOO::add_stuff;
  cout<<(this->*fptr)(a,b)<<endl;
 }
};

class BAR
{
public:
 int add_stuff(int a, int b)
 {
  return a+b;
 }
 void call_adder(int a, int b)
 {  
  //int (BAR::*fptr)(int a, int b);
  //fptr = &BAR::add_stuff;
  //cout<<(*fptr)(a,b)<<endl;
 }
};

int main()
{
 FOO test;
 test.call_adder(10,20);
 return 0;
}
like image 589
Jacob Avatar asked Jun 23 '26 10:06

Jacob


2 Answers

Apparently, you misunderstand the meaning of this->* in the call in FOO.

When you use this->* with the member fptr pointer, the this->* part has absolutely nothing to do with fptr being a member of FOO. When you call a member function using a pointer-to-member, you have to use the ->* operator (or .* operator) and you always have to specify the actual object you want to use with that pointer-to-member. This is what the this->* portion of the calling expression does. I.e. the call will always look as

(<pointer-to-object> ->* <pointer-to-member>) (<arguments>)

or as

(<object> .* <pointer-to-member>) (<arguments>)

The left-hand side of the call (<pointer-to-object> or <object> above) cannot be omitted.

In other words, it doesn't matter whether fptr is a member variable, local variable, global variable or any other kind of variable, the call through fptr will always look as

(this->*fptr)(a, b);

assuming that you want to invoke it with *this object. If, for another example, you want to invoke it for some other object pointed by pointer pfoo, the call will look as follows

FOO *pfoo;
...
(pfoo->*fptr)(a, b);

In your BAR class the call should look as (this->*fptr)(a,b) even though fptr is a local variable.

like image 171
AnT Avatar answered Jun 26 '26 02:06

AnT


When you use a member function pointer, you need to specify the object on which it is acting.

I.e. you need to create a pointer to an instance of BAR (let's call it bar) and do:

(bar->*fptr)(a,b)

to call the function, or an instance of BAR and do:

(bar.*fptr)(a,b)

Put another way:

#include <iostream>

class BAR
{
    int i;
public:
    BAR(): i(0) {};
    int AddOne() { return ++i; };
    int GetI() { return i; };
}

int main()
{
    BAR bar;
    auto fPtr = &BAR::AddOne; // This line is C++0x only (because of auto)
    std::cout << (bar.*fPtr)(); //This will print 1 to the console
    std::cout << std::endl;
    std::cout << bar.GetI(); //This will also print 1 to the console.
}
like image 28
Billy ONeal Avatar answered Jun 26 '26 02:06

Billy ONeal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!