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 bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Declaring Function Pointers

Status
Not open for further replies.

Kalisto

Programmer
Feb 18, 2003
997
GB
I have a struct which I wish to contain a function pointer.

in the struct it is declared as

int (*pValidate)(byte*,std::istream*);//function Pointer

In the same .h file I have the function declared as

class foo
{
public:
int __cdecl ValidateUL(byte* pData,std::istream* S);
...
}

In my .cpp file I have the lines

MyStruct D;
D.pValidate = &foo::ValidateUL;

But when I try to compile it I get an error message. I assume it is something to do with the way I have declared the f.p, or am allocating it, but I can't see what.

Any ideas ?

K
 
Oops, sorry.
It's
d:\Matt\Projects\Vis C++\DicomReader\DicomReader\DicomLibrary.cpp(34): error C2440: '=' : cannot convert from 'int (__cdecl DicomLibrary::* )(byte *,std::istream *)' to 'int (__cdecl *)(byte *,std::istream *)'

To me it seems that there shouldn't be a problem as it is trying to convert like for like.

K
 
Looks like you need a memberfunction pointer and not just a function pointer. Those a so much more fun :) Please see group 0002, and element 0000 for more group info :p

Matt

P.S. Sorry for the bad joke with group and element. It is DICOM related.
 
int (*pValidate)(byte*,std::istream*);

that is a pointer to a non class function which is not of the same type as a function pointer to a class function. Thats why you are getting the error message.

you need to declare the pointer as :
int (foo::*pValidate)(byte*,std::istream*);
 
Nope, if I do that I get "No Qualified Name for Pointer to member (found '::*')"

And if I put int(*foo::pValidate)() I get the original error message again.

K
 
Zyrethian, no Problem ;-) when I first tried to work out how to make a system that would allow for the 27 types, validate them and format them I thought it was all a joke as well !

K
 
Have you managed to find the answer?

One way of getting around this problem is by defining your function foo() as a non-member function. To get access to your class you can pass a pointer to your class through (use the variable 'this').

ie.

int Foo(int Param1, char* Param2, BarClass* Param3)
{
BarClass* pThis = Param3;

pThis->MemberFunction();
}

or you can use a pointer to null to pass any class through:

int Foo(int Param1, char* Param2, void* Param3)
{
BarClass* pThis = NULL;
pThis = (BarClass *)Param3;

pThis->MemberFunction();
}

Skute

"There are 10 types of people in this World, those that understand binary, and those that don't!"
 
The problem is I have a 27 different validation functions, and I want a simple vector of an index, and a function pointer to the appropriate validation function (maybe they shouldn't be in a class), so I can just look up the appropriate function and call it via a vector, rather than have a large select case statement.
I'll try your suggestion, but am open to other ideas as well.

K
 
In my opinion you try to reinvent polimorphism.

class c
{
public:
virtual void doSomething() = 0;//abstract
};
class c1: public c
{
public:
virtual void doSomething(){..do something...}
};
........
class c27: public c
{
public:
virtual void doSomething(){...do other thing..}
};

vector<c*> do_holder;

do_holder.push_back(new c1);
...
do_holder.push_back(new c27);

for(int i = 0; i < 17; i++)
{
do_holder.doSomething();
}

Ion Filipski
1c.bmp

ICQ: 95034075
AIM: IonFilipski
filipski@excite.com
 
The correct for loop:
Code:
for(int i = 0; i < 17; i++)
{
   do_holder[i].doSomething();
}

Ion Filipski
1c.bmp

ICQ: 95034075
AIM: IonFilipski
filipski@excite.com
 
We can't mix pointers to ordinary and non-static member functions because of member function call is indeed an operation on the real object (class instance). It's obviously, no any object reference in a simple function pointer. It's code address - that's all.
On the other hand we may treat a simple function call as operation on a program environment, not an object.
You may declare in-class validators as static member functions and get its addresses as usually:
Code:
typedef int (*vf)(byte*,std::istream*);
...
class Xyz { 
public: 
static int f(byte*,std::istream*); ... }; // member validator
// What for cdecl here?..
...
int f(byte*,std::istream*); // free function validator
...
vf v[] = { Xyz::f, f, ..., 0 }; // gets all... 

if (v[i](.,.)) ... // call ith func...
But why do you need member/ordinary functional mixture? Fast switching? Where is your 27 types? You have 1 (one) function signature with byte* and iostream* args. If you control these types (classes?) code then add 27 validation member functions, but what iterator can walk over your 27-colored container?
It seems fast switch is not the solution of the real problem. May be I'm wrong...
 
Maybe I don't explain my problem too well. (I have a working solution now, but I am not sure if it is the best one)

My data stream contains Sets of data. There can be many hundreds of sets of data in a file / stream, but each set will conform to one of 27 'Types'. The 27 Types are currently Instances of a Class that contains all the essential information I need to read in and interpret that type, along with a function to Read in the Data, and another to take a string of data and format it into a set for output.

Rather than have a single class with 27 different validator functions and 27 Format functions, I have the 54 functions in an include file, and when I set up ,my type validation library (happens once in the program) I assign each of my instances a pointer to a format and a pointer to a validate function. So now each instance of my Type validator objects knows about only one validate function, not the 27 that it new about previously.

These 27 instances are in a single vector, and I have 1 function that reads in the start of the data set, and then searches the vector for the correct validation instance. This instance is then used in the code, simply as myInstance.validate(), rather than me having 2 loops, each of which had to decide which function to call. I am sure that there is little difference in the speed of the code execution, but for the sake of adding in one more function, this vector and some initialisation code, the code to read in and validate, or format and output data is very simple.

If anyone can think of other more elegant, or quicker ways,then feel free to comment. (though we are getting away from C++ and into design now)

Thanks to you all for your input, as usual, whether I sort it myself or someone in here sorts it, I learn something new !

K
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top