I want to define a member function in class and use its pointer. I know that I can use static member function but the problem with it is that I can only access the static members of the class. Is there a way other than static member function to be able to get function pointer.
To be more specific: There is a library which I'm using which gets a function pointer as its input. I want to write a member function and assign its function pointer to that external library. Should I create an object of class or use this pointer to do this?
You can get the pointer of the method, but it has to be called with an object
typedef void (T::*MethodPtr) ();
MethodPtr method = &T::MethodA;
T *obj = new T();
obj->*method();
If you need to have non-object pointer and you want to use object then you have to store instance of object somewhere, but you are restricted to use only one object (singleton).
class T {
static T *instance;
public:
T::T() {
instance = this;
}
static void func() {
instance->doStuff();
}
void doStuff() {}
};
If library supports user data for function pointers, then you may have multiple instances
class T {
public:
static void func(void *instance) {
((T*)instance)->doStuff();
}
void doStuff() {}
};
If:
you want to get the function pointer of a nonstatic member from within the class
And use it within the class:
Then:
It can work, because when you get the member function address, there is a "this" pointer. The syntax was not obvious to me, and it may look somewhat ugly, but not TOO bad.
This may not be new to the true experts, but I have wanted to have this in my bag of tricks for a long time.
Here is a complete sample program:
#include <iostream>
class CTestFncPtr
{
public:
CTestFncPtr(int data) : mData(data)
{
// Switch = &CTestFncPtr::SwitchC; // Won't compile - wrong function prototype - this is type safe
if (data == 1)
Switch = &CTestFncPtr::SwitchA;
else
Switch = &CTestFncPtr::SwitchB;
}
void CallSwitch(char *charData)
{
(this->*Switch)(charData);
}
private:
void SwitchA(char * charData)
{
std::cout << "Called Switch A " << "Class Data is " << mData<<" Parameter is " << charData<< "\n";
Switch = &CTestFncPtr::SwitchB;
}
void SwitchB(char * charData)
{
std::cout << "Called Switch B " << "Class Data is " << mData<<" Parameter is " << charData<< "\n";
Switch = &CTestFncPtr::SwitchA;
}
void SwitchC()
{
}
void(CTestFncPtr::*Switch)(char * charData);
int mData;
};
int main(int argc, char * argv[])
{
CTestFncPtr item1(1);
item1.CallSwitch("Item1");
item1.CallSwitch("Switched call Item 1");
CTestFncPtr item2(0);
item2.CallSwitch("Item2");
item2.CallSwitch("Switched call Item 2");
return 0;
}
Related
I'm testing, trying to call a member function being passed as a parameter,
the member function has to be one of another class.
this is an example, which gives an error:
"pointer-to-member selection class types are incompatible ("B" and
"A")"
This is the code, what am I doing wrong?
#include <iostream>
using namespace std;
class A {
private:
public:
void fA(int x) {
cout << "hello" << endl;
}
void fB(int x) {
cout << "good bye" << endl;
}
A() {
}
};
class B {
private:
void (A:: * f)(int) = NULL;
public:
B(void (A:: * f)(int)) {
this->f = f;
}
void call() {
(this->*f)(10); //What's wrong here?
}
};
A a = A();
B b = B(&(a.fA));
B b2 = B(&(a.fB));
int main(void) {
b.call();
b2.call();
}
&(a.fA) is not legal C++ syntax. &A::fA is. As you can see, there is no object of type A anywhere of this syntax. &A::fA is just a pointer to a member function, not a pointer-to-member-together-with-an-object combo.
Now in order to call that pointer-to-member, you need an object of class A. In class B, you don't have any. You need to get one in there somehow, and call the function this way:
(a->*f)(10);
where a is a pointer to that object of class A.
Let me start stating I'm a self-made programming passionate, so forgive the unprofessional language, not speaking English very well I got support from translator. From what I've understood it seems that casting a pointer to an object and one of its functions member cannot be made to a dummy structure. In particular, the call to the member function cannot be made in this way:
#include <iostream>
struct _T{};
class Class1
{
public:
void print()
{ std::cout << "Class1::print ...." << std::endl; }
int sum(int value)
{ return m_dato+value; }
private:
int m_dato { 10 };
};
int main()
{
Class1 item;
void(_T::*func)();
int(_T::*fsum)(int);
Class1* p1=&item;
auto p2=reinterpret_cast<_T*>(p1);
func =reinterpret_cast<void(_T::*)()>(&Class1::print);
(p2->*func)();
fsum =reinterpret_cast<int(_T::*)(int)>(&Class1::sum);
auto dato=(p2->*fsum)(55);
std::cout << "Dato: " << dato << std::endl; // ok 65..
std::cout << "Fine procedura ...." << std::endl;
return 0;
}
Now besides guessing that the pointer to Class1 may not be contained in the _T pointer, I don't understand why this code works without problems on all conditions (in case the class is derived and the function is virtual, in the case of multiple inheritance, in the case that the function is present only in the base class, etc ...). At the end I'm not telling the compiler to call an address of a class (Class1), that the compiler knows well, and that this function is at some offset from the class pointer and that the signature of that function is similar to the one stored later after the cast.
I want to make a class where there is a function that is called automatically, to process information stored within this classes instance.
However each instance has different values and possibly a different way for that content to be handeled.
Therefore I need something simmilar to constructor overloading but in a member function. Where every instance can overload the default function or leave it up to the default to handle the input.
How can that be achieved?
Try to Call Functions in Constructor with if else condition
like:
class abc{
abc(){
if username == "member 1"
functioncall();
else
functioncall();
}
}
As far as I see you need some virtual construction emulation. There is a simple C/C++ way to do it.
// Example program
#include <iostream>
#include <string>
struct A;
typedef void (*cb)(A*);
struct A
{
int m_a;
static void foo(A* aref)
{
std::cout << "Print a: " << aref->m_a << "\n";
}
A(cb b=foo)
{
m_a = 100;
b(this);
}
};
int main()
{
A a;
}
It is not very clear, but still does the trick.
By creating a separate class for the variable behavior Callable describes the local data relating to the function, and by being a class, can be derived.
class Callable {
public:
int m_Value;
Callable(int value) : m_Value(value)
{
}
void operator()( int val1, double val2 /* whatever makes sense */ ) {
}
};
Using the function operator void operator()( ...... ) we create a way of making variables of type Callable to look like a function.
class Variable {
public:
Callable myFunction;
Variable(const Callable & howToCall, /* some more stuff */) :
myFunction(howToCall)
{ /* stuff */
}
void aFunction(int data, double value ) {
myFunction( data, value);
}
};
When calling aFunction the current value of myFunction is called.
Finally Variable can change which function it calls, by modifying the value of myFunction....
myFunction = Callable( /* new parameters */ );
can you please explain me why this code shows nothing except for the last std::cout line in main()? Checked through similar threads on stackoverflow.com, was not able to connect them to mine, is this pointing legal at all? I try to set a function pointer of a class to another class function:
#include <iostream>
class container;
class one {
public:
one()
{
eventsHandler = NULL;
};
~one() {};
void (container::*eventsHandler)();
};
class container {
public:
container()
{
zone = new one;
zone->eventsHandler = &container::events;
};
~container()
{
delete zone;
};
one *zone;
void events()
{
std::cout << "event handler is on..." << std::endl;
};
};
int main()
{
container *test = new container;
test->zone->eventsHandler;
std::cout << "just checker..." << std::endl;
delete test;
system("pause");
};
You should use operator->* for calling the member function pointer, and assign test as the object which will be called on,
(test->*test->zone->eventsHandler)();
or more clear,
(test->*(test->zone->eventsHandler))();
LIVE
You need to provide an object to call a pointer to memeber function:
container *test = new container;
(test->*test->zone->eventsHandler)();
Here, test is the object, test->zone->eventsHandler is the pointer to member function that you have saved, and operator->* joins them.
So, it is very much like any other member function; however, you can switch which objects to call a member on:
container *first = new container;
container *second = new container;
(first->*second->zone->eventsHandler)();
// both pointers point to the same function
std::cout << (first->zone->eventsHandler == second->zone->eventsHandler) << std::endl;
You have to actually call the function pointer, in line 38, as:
(test->*test->zone->eventsHandler)();
I want the Windows thread pool (QueueUserWorkItem()) to call my class' member functions.
Unfortunately this cannot be done directly by passing a member function pointer as an argument to QueueUserWorkItem().
What makes it difficult is that more than one member function must be callable and they have different signatures (all return void though).
One probably need to add a few layers of abstraction to get this to work, but I'm not sure how to approach this. Any ideas?
This might help.
You can use tr1::function () and tr1::bind to "coalesce" various calls:
#include <iostream>
#include <tr1/functional>
using namespace std;
using namespace tr1;
class A
{
public:
void function(int i) { cout << "Called A::function with i=" << i << endl; }
};
void different_function(double c) {
cout << "Called different_function with c=" << c << endl;
}
int main(int argc, char* argv[])
{
function<void()> f = bind(different_function, 3.14165);
f();
A a;
f = bind(&A::function, a, 10);
f();
return 0;
}
The address of the function object can be passed as a single callable object (needing only one address).
Example:
In your class add:
char m_FuncToCall;
static DWORD __stdcall myclass::ThreadStartRoutine(LPVOID myclassref)
{
myclass* _val = (myclass*)myclassref;
switch(m_FuncToCall)
{
case 0:
_val->StartMyOperation();
break;
}
return 0;
}
Make a member for adding to queue then
void myclass::AddToQueue(char funcId)
{
m_FuncToCall=funcId;
QueueUserWorkItem(ThreadStartRoutine,this,WT_EXECUTEDEFAULT);
}
or create
typedef void (*MY_FUNC)(void);
typedef struct _ARGUMENT_TO_PASS
{
myclass* classref;
MY_FUNC func;
}ARGUMENT_TO_PASS;
and then
void myclass::AddToQueue(MY_FUNC func)
{
ARGUMENT_TO_PASS _arg;
_arg.func = func;
_arg.classref = this;
QueueUserWorkItem(ThreadStartRoutine,&_arg,WT_EXECUTEDEFAULT);
}
If you need further explanation feel free to ask :)
EDIT: You'll need to change the ThreadStartRoutine for the second example
and you can also change the struct to hold the passing argument