Sign in to follow this  
Chrysaor

Function Pointers in c++ classes

Recommended Posts

Hi, My problem concerns function pointers. I'll simplify things. I have this index class. It creates an index from records. The index uses hashing. This function is sent as a function pointer in the constructor of the index class. Like so: class Index { Index(..., int (*hashing)(int)) .. } Now, an instance of the index class is created another class. This class has the hashing function. lets called it hFunct. The index is created in the constructor. like so: class MyClass { .... Index *index; int hFunct(int k); ... } MyClass::MyClass() { ... index = new Index(..., &hFunct); ... } The problem lies with the &hFunct. It gives me an "illegal operation on bound member function expression" when i try to compile. I've tried many attempts of using the this pointer, of creating the index in another method. The only thing that seems to work is if the hashing function isnt part of a class. Is there a way i can accomplish passing the function pointer to the constructor or am i doomed? Thx for the help!

Share this post


Link to post
Share on other sites
A pointer to a (non-static) member function is not the same thing as a function pointer. &MyClass::hFunct is not an int (*)(int), but a int (MyClass::*)(int).

In particular, bound member functions (member functions which are associated with a particular object) cannot be manipulated in any way, except for immediately calling them.

In your code, hFunct refers to this->hFunct, which is a bound member function (it is associated with "this" object).

You must explicitely refer to &MyClass::hFunct (with the class name), and only associate the object the member functions works on when you are actually calling it.


class Index
{
Index(...,MyClass* object, int (MyClass::*hashing)(int))
};

MyClass::MyClass()
{
index = new Index(..., this, &MyClass::hFunct);
}


And you will call it with (object->*hashing)(x).

Share this post


Link to post
Share on other sites
what Fruny says is, of course, technically correct, but IMHO a cleaner way to do this (dear god is there an uglier syntax in all of creation then function pointers? [smile]) is to require your "creator" class to implement a hashing method with a particular signature (which it pretty much has to anyway) and call that method. This is easily done using an abstract base class.

so you have

class CreatorBase
{
public:
virtual int HashMethod(int) = 0;
}

class Index
{
Index(CreatorBase& creator)
{
creator.HashMethod();
}
}

class MyClass : public CreatorBase
{
public:
// error if not implemented
virtual int HashMethod(int)
{
return dope;
}
}




As I said, IMHO, this is cleaner then using a function pointer unless you have a specific reason for using them. Someone correct me if I'm missing something glaringly obvious....

[edit] my speeling is alwuf.....

Share this post


Link to post
Share on other sites
Pointer-to-member-function takes up to 16 bytes of storage, because it has to deal with all kinds of cross-cast cases. It's usually a bad idea to use it if you can think of better ways. Better ways may include:

1) a virtual on the class being hashed
2) a traits template that you specialize on the class in question
3) a separate hash interface that you create and pass in with the object

Note that calling a virtual function on an object is usually slightly cheaper than calling a pointer-to-member-function on an object.

I'd recommend going with the traits template if you have type information at the point you need to hash.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this