Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

pointer to member function

Status
Not open for further replies.

gRegister

Programmer
Nov 28, 2002
9
US
I'm having trouble accomplishing this without using a wrapper class. This all worked in Visual C++ except for the function call itself, which gave the following error
"illegal on operands of type 'int (__thiscall FPclass::*)(void)' "
It comes down to two questions.
1. Is their a ANSI compliant way to create a vector of member function pointers in the class which owns these member functions.
2. Once this vector is filled, How do we call the member function through the vector.
NOTE: Bjarne Stroustrup discusses something similar in "the C++ programming language" in section 18.4.4.2
//______here's the code and thanks_____
#include <iostream>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
class FPclass
{
public:
FPclass();
~FPclass();
int CallMemberFunction(int option);
private:
int func1(void);
vector<int ( FPclass::*)(void)> functions;
};
FPclass::FPclass()
{
functions.push_back(&FPclass::func1);
}
FPclass::~FPclass()
{
}
int FPclass::func1(void)
{
cout << &quot;member function 1 has been called&quot; << endl;
return 1;
}
int FPclass::CallMemberFunction(int option)
{
(*functions[option]) ();
return 1;
}
//***********************************************
int main(int argc, char* argv[])
{
FPclass fp;
fp.CallMemberFunction(0);
return 0;
}
 
Method pointer can be a bit confusing. It is usually easier to use a typedef to define them so you dont need to type all the obscurity.

typedef type(class::*typedef_name)();

in your case

typedef int(FPClass::*FPMethodPtr)();

// i have never used vector, i just us arrays
// but from what you have typed, I assume this
// will be fine
vector<FPMethodPtr> functions;

// the constructor should be able to remain unchanged
// except for the argument
FPclass::FPclass()
{
functions.push_back(func1);
}


// the CallMemberFunction should change to
int FPclass::CallMemberFunction(int option)
{
// Please note you are not returning
// the return value from the function
// call
(this->*functions[option])();
return 1;
}


That should do it for you. The typedef can be done within the class as well in either public,protected or private.


Good Luck
Matt
 
Also, you need to make sure &quot;option&quot; is valid. (I would think)

Matt
 
You are correct about how to call the function. As you stated the below worked.
(this->*functions[option])();
However this will not work.
typedef int (FPclass::*FuncPointer)(void);
vector<int (FuncPointer)(void)> functions;
I get the following error
&quot;C:\Program Files\Microsoft Visual Studio\MyProjects\fp\fp.cpp(21) : error C2275: 'FPclass::FuncPointer' : illegal use of this type as an expression&quot;
That was a Visual C++ error, Borland Builder yeilds
&quot; improper use of typedef 'FPclass::*FuncPointer ()' &quot;
Also Borland won't except
vector<int (FPclass::*)(void)> functions;
Which suggest to me that the code that works in Visual C++ is not ANSI compliant.
Also the assignment of the vector you suggest will not work.
functions.push_back(func1);
It must be
functions.push_back(&FPclass::func1);
Thanks very much for your help!
I will continue to determine if this can be made ANSI compliant. If you discover anything along those lines I would greatly appreciate you passing it on to gullybranch@netscape.net
Thanks again,
Gary

//____below is the new Visual C++ working code if you interested___

#include &quot;stdafx.h&quot;
#include <iostream>
#include <stdlib.h>
#include <string>
#include <vector>

using namespace std;

class FPclass
{
public:
FPclass();
~FPclass();
int CallMemberFunction(int option);
private:
int func1(void);
typedef int (FPclass::*FuncPointer)(void);
vector<int ( FPclass::*)(void)> functions;
};

FPclass::FPclass()
{
functions.push_back(&FPclass::func1);
}

FPclass::~FPclass() {}
int FPclass::func1(void)
{
cout << &quot;member function 1 has been called&quot; << endl;
return 1;
}

int FPclass::CallMemberFunction(int option)
{
(this->*functions[option])();
return 1;
}

//***********************************************

int main(int argc, char* argv[])
{
FPclass fp;
fp.CallMemberFunction(0);

return 0;
}


 
the following wont work?

vector<FuncPointer> functions;

FuncPointer is typedefed as


typedef int (FPclass::*FuncPointer)(void);

So typing

vector<int ( FPclass::*)(void)> functions;

should have the same effect as

vector<FuncPointer> functions;

Matt


 
I completely agree that the typedef should work, but it will only compile using
vector<int ( FPclass::*)(void)> functions;
i think i need to understand more about binders and adapters, as Bjarne Stroustrup explain them in his book.
Since he made the revsion to allow member function pointers in C++, i'm wondering if i'm not trying to circumvent something that he didn't want done. or if maybe this revisions was not made to include vector alloacation. Not sure what the deal is here, maybe someone will explain.
 
>> maybe someone will explain.

maybe you will explain why you need a collection of function pointers?

they are not generally used in object oriented design.

-pete
 
See your email... i sent you a .cpp file with FuncPOinter in the vector declaration.

Matt
 
It acually started to better understand the relationship of static and virtual member functions. It has grown int o the monster we speak of now. The idea was to create an object which contained a list of functions commonly used in some application. Let's say i'm processing messages from some device and I have defined all the functions that I will need to sevice this type of device. But for some reason, the message format keeps changing as the project progesses. All i would need to do is restructor my vector of member function pointers to execute the correct function. This could be done even at run time if i give access to the vector or better yet use inheritance and do it in a sub-class. Also even though it is a minor time difference, it can be quicker to use function pointers. Let's say that I have 1000 possible functions to choose from, what quicker way than to create a one-to-one relationship by way of a index into a vector.
 
>> Let's say i'm processing messages from some device

sounds like you could use a &quot;chain of responsibility&quot; pattern or maybe a &quot;command&quot; pattern.

google software pattern &quot;chain of responsibility&quot;

good luck
-pete
 
thanks i'll take a look at patterns. however the original proposal still seems worthy of investigation, if for no other reason than to better understand.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top