I tried to implement a function pointer calling to the class member. I have implemented the sample and assigned the function pointer successfully. But if I try to call the function pointer it is throwing an error. Kindly refer below sample code of what I implemented and assist me on this.
#include <iostream>
using namespace std;
class myfunpoin
{
public:
int addd(int a,int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
};
int main()
{
myfunpoin a;
int (myfunpoin::*myval)(int, int);
myval =&myfunpoin::addd;
myval(1, 2);//i want to invoke this function pointer but getting error
getchar();
return 0;
}
myval(1, 2);
This cannot work because you haven't passed the implicit instance argument.
A pointer to member function is called like a member function, except in place of the function name, you have indirection operator and the pointer to member function. Example:
(a.*myval)(1, 2);
The parenthesis are needed because function call operator has higher precedence and the expression would have a wrong meaning otherwise.
Related
I am trying to wrap my head around passing method as function argument. Here is a simplified example which returns a compilation error that I don't understand
class B
{
private:
int j;
public:
void foo(int i){std::cout << i + this->j << std::endl;}
void setj(int J){j=J;}
};
class A
{
private:
B b;
public:
void call(void (B::*fun)(int i), int i) { b.*fun(i); }
void setBj(int j){b.setj(j);}
};
int main()
{
A a;
a.setBj(40);
a.call(B::foo, 2);
}
When compiled with
g++ -std=c++11 b.cpp -o b
I get
b.cpp:22:50: error: called object type 'void (B::*)(int)' is not a function or
function pointer
void call(void (B::*fun)(int i), int i) { b.*fun(i); }
~~~^
b.cpp:31:12: error: call to non-static member function without an object
argument
a.call(B::foo, 2);
~~~^~~
2 errors generated.
I don't understand the first error message. I understand that I am calling foo as if it was a static method, which it is not but I don't understand how to pass a non-static method.
Two problems.
To invoke a pointer to a member function, you need to first apply a pointer to member access operator, that obtains a callable expression. Then you add a call. Now it just so happens that .* is of lower precedence than the function call operator. So the first fix:
(b.*fun)(i)
A a pointer to member function can only be obtained by applying unary & on the fully qualified function name. So the second fix:
a.call(&B::foo, 2);
Hi it is my first experience with passing function pointer in C++.
So here is my code:-
#include <iostream>
using namespace std;
// Two simple functions
class student
{
public:
void fun1() { printf("Fun1\n"); }
void fun2() { printf("Fun2\n"); }
// A function that receives a simple function
// as parameter and calls the function
void wrapper(void (*fun)())
{
fun();
}
};
int main()
{ student s;
s.wrapper(s.fun1());
s.wrapper(s.fun2());
return 0;
}
Initially in wrapper function i passed only fun1 and fun2.I got an error
try.cpp:22:15: error: ‘fun1’ was not declared in this scope
s.wrapper(fun1);
^~~~
try.cpp:23:15: error: ‘fun2’ was not declared in this scope
s.wrapper(fun2);
Later I tried to pass s.fun1() and s.fun2() as argument but again got error
try.cpp:23:23: error: invalid use of void expression
s.wrapper(s.fun1());
^
try.cpp:24:23: error: invalid use of void expression
s.wrapper(s.fun2());
Please help I don't know what to do :(
Let's deal with the two issues in the post.
You are calling fun1 and fun2. Since their return type is void, you can't pass their result as something's value. In particular as the value of a function pointer. You also can't obtain their address by using the dot member access operator. Which brings us to the following.
Member functions are not like regular functions. You cannot just take their address. Their treatment is special, because member functions can only be called on an object. So there's a special syntax for them, which involves the class they belong to.
Here's how you would do something like what you are after:
class student
{
public:
void fun1() { printf("Fun1\n"); }
void fun2() { printf("Fun2\n"); }
// A function that receives a member function
// as parameter and calls the function
void wrapper(void (student::*fun)())
{
(this->*fun)();
}
};
int main()
{ student s;
s.wrapper(&student::fun1);
s.wrapper(&student::fun2);
return 0;
}
I am trying to pass a member function as argument using pointer-to-member-function. I have already seen some links like this here but I could not solve the problem.
The class Foo has two member functions. I need to pass the addition function as an argument to the NewOper function.
This is my code. I can correctly use pointer to call the addition function but it gives me an error when I try to pass it as an argument to NewOper function. I appreciate it if you tell me how I can fix it. (The last two lines cause error)
#include <iostream>
using namespace std;
class Foo{
public:
int addition(int a, int b)
{
return (a + b);
}
int NewOper(int x, int y, int(*fnc2call)(int, int))
{
int r;
r = (*fnc2call)(x, y);
return (r);
}
};
int main()
{
int m,n, k, l;
int (Foo::*fptr) (int, int) = &Foo::addition;
Foo obj;
m=(obj.*fptr)(1,2);
Foo* p = &obj;
n=(p->*fptr)(3,4);
cout << m << endl;
cout << n << endl;
//**********************
int (Foo::*fptr) (int, int, int(*fnc2call)) = &Foo::NewOper;
k = (obj.*fptr)(1, 2, addition);
}
You already have answer in your own code:
int (Foo::*fptr) (int, int) = &Foo::addition - here you correctly declared fptr as pointer to function, which is (non static) member of class Foo
But you forgot to do the same in you NewOper function definition:
int NewOper(int x, int y, int(*fnc2call)(int, int)) - this function wants address of free function as 3rd argument. Redefine it in the same way you declared fptr. But then you'll need to pass also pointer to an object of class Foo to this function
Alternatively, you can make your function addition function static as Jarod42 suggested (actually, the way it is written now, there is no reason for it to be member of class Foo unless you have further plan on it). Then you'll need to remove Foo:: from fptr definition
Alright, I think the title is sufficiently descriptive (yet confusing, sorry).
I'm reading this library: Timer1.
In the header file there is a public member pointer to a function as follows:
class TimerOne
{
public:
void (*isrCallback)(); // C-style ptr to `void(void)` function
};
There exists an instantiated object of the TimerOne class, called "Timer1".
Timer1 calls the function as follows:
Timer1.isrCallback();
How is this correct? I am familiar with calling functions via function pointers by using the dereference operator.
Ex:
(*myFunc)();
So I would have expected the above call via the object to be something more like:
(*Timer1.isrCallback)();
So, what are the acceptable options for calling functions via function pointers, as both stand-alone function pointers and members of an object?
See also:
[very useful!] Typedef function pointer?
Summary of the answer:
These are all valid and fine ways to call a function pointer:
myFuncPtr();
(*myFuncPtr)();
(**myFuncPtr)();
(***myFuncPtr)();
// etc.
(**********************************f)(); // also valid
Things you can do with a function pointer.
1: The first is calling the function via explicit dereference:
int myfunc(int n)
{
}
int (*myfptr)(int) = myfunc;
(*myfptr)(nValue); // call function myfunc(nValue) through myfptr.
2: The second way is via implicit dereference:
int myfunc(int n)
{
}
int (*myfptr)(int) = myfunc;
myfptr(nValue); // call function myfunc(nValue) through myfptr.
As you can see, the implicit dereference method looks just like a normal function call -- which is what you’d expect, since function are simply implicitly convertible to function pointers!!
In your code:
void foo()
{
cout << "hi" << endl;
}
class TimerOne
{
public:
void(*isrCallback)();
};
int main()
{
TimerOne Timer1;
Timer1.isrCallback = &foo; //Assigning the address
//Timer1.isrCallback = foo; //We could use this statement as well, it simply proves function are simply implicitly convertible to function pointers. Just like arrays decay to pointer.
Timer1.isrCallback(); //Implicit dereference
(*Timer1.isrCallback)(); //Explicit dereference
return 0;
}
You don't have to dereference a function pointer to call it. According to the standard ([expr.call]/1),
The postfix expression shall have
function type or pointer to function type.
So (*myFunc)() is valid, and so is myFunc(). In fact, (**myFunc)() is valid too, and you can dereference as many times as you want (can you figure out why?)
You asked:
Timer1 calls the function as follows:
Timer1.isrCallback();
How is this correct?
The type of Timer1.isrCallback is void (*)(). It is a pointer to a function. That's why you can use that syntax.
It is similar to using:
void foo()
{
}
void test_foo()
{
void (*fptr)() = foo;
fptr();
}
You can also use:
void test_foo()
{
void (*fptr)() = foo;
(*fptr)();
}
but the first form is equally valid.
Update, in response to comment by OP
Given the posted definition of the class you would use:
(*Timer1.isrCallback)();
To use
(Timer1.*isrCallback)();
isrCallback has to be defined as a non-member variable of whose type is a pointer to a member variable of TimerOne.
void (TimerOne::*isrCallback)();
Example:
#include <iostream>
class TimerOne
{
public:
void foo()
{
std::cout << "In TimerOne::foo();\n";
}
};
int main()
{
TimerOne Timer1;
void (TimerOne::*isrCallback)() = &TimerOne::foo;
(Timer1.*isrCallback)();
}
Output:
In TimerOne::foo();
(Test this code)
If you want to define isrCallbak as a member variable of TimerOne, you'll need to use:
#include <iostream>
class TimerOne
{
public:
void (TimerOne::*isrCallback)();
void foo()
{
std::cout << "In TimerOne::foo();\n";
}
};
int main()
{
TimerOne Timer1;
Timer1.isrCallback = &TimerOne::foo;
// A little complicated syntax.
(Timer1.*(Timer1.isrCallback))();
}
Output:
In TimerOne::foo();
(Test this code)
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;
}
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.
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.
}
I don't think the usage of the variable itself is illegal. What's illegal is trying to call that method without a class instance.
That is, you should really call (someVar->*fptr)(a,b) where someVar is of type BAR*
BAR::call_adder() had a couple of problems. For one, you were mixing case. In C++, case is signifigant. BAR and bar are not the same. Second, you decalred and assigned the pointer fine, after fixing the case problems, but when you try to call through the pointer to a member function, you need to use operator ->* with a class object. Here's is call_adder() fixed
void call_adder(int a, int b)
{
int (BAR::*fptr)(int a, int b);
fptr = &BAR::add_stuff;
cout<<(this->*fptr)(a,b)<<endl;
}
When you invoke a member function of a class the compiler generates code to set 'this' while the function runs. When you call it from a function pointer that isn't done. There are ways to get around it but they aren't 'guaranteed' to work and are compiler dependent. You can do it as long as you're careful and know the possible problems you can run into.