C++ Call Pointer To Member Function
Asked Answered
C

4

41

I have a list of pointers to member functions but I am having a difficult time trying to call those functions... whats the proper syntax?

typedef void (Box::*HitTest) (int x, int y, int w, int h);

for (std::list<HitTest>::const_iterator i = hitTestList.begin(); i != hitTestList.end(); ++i)
{
    HitTest h = *i;
    (*h)(xPos, yPos, width, height);
}

Also im trying to add member functions to it here

std::list<HitTest> list;

for (std::list<Box*>::const_iterator i = boxList.begin(); i != boxList.end(); ++i)
{
    Box * box = *i;
    list.push_back(&box->HitTest);
}
Circumspect answered 11/2, 2013 at 14:32 Comment(4)
define "having a difficult time"Bookstall
Its not working lol and I can't get it to workCircumspect
Are you sure you want to do things this way, and not using a list of Box elements and a virtual function?Modestamodeste
The first code I am getting the error "error C2276: '&' : illegal operation on bound member function expression" For the second code snippit I am getting the syntax error "Error: Expression must have a pointer type" with that syntax"Circumspect
T
60

Pointers to non-static member functions are a unique beast with unique calling syntax.

Calling those functions require you to supply not just named parameters, but also a this pointer, so you must have the Box pointer handy that will be used as this.

(box->*h)(xPos, yPos, width, height);
Titter answered 11/2, 2013 at 14:33 Comment(6)
I get the error "Error: Expression must have a pointer type" with that syntax.Circumspect
@JC. Here, try this: parashift.com/c++-faq/macro-for-ptr-to-memfn.htmlMacswan
Something like ((*this).*h)(xPos, yPos, width, height) but I prefer to stay awayMohan
The issue there is that I am traversing the list of member function pointers and calling each function in another object not of the type that owns the method. Where I am calling the member function pointer I do not have the instance of the object that has the member function I am callingCircumspect
@JC That won't work. You need both: An object that will act as this, and a pointer to a non-static member function.Weak
Ah bummer... I'm essentially trying to simulate "events" by registering a bunch of instance member methods into a list in another class so I can iterate through them and call them, so that those instances are "listening" to this class that is maintaining the list and can react when something happens. Maybe there is a better approach in C++?Circumspect
M
16

Calling a member function through a pointer to member function has a particular syntax:

(obj.*pmf)( params );   //  Through an object or reference.
(ptr->*pmf)( params );  //  Through a pointer.

Although ->* can be overridden, it isn't in the standard library iterators (probably because it would require overrides for every possible function type). So if all you've got is an iterator, you'll have to dereference it and use the first form:

((*iter).*pmf)( params );

On the other hand, iterating over a the pointer to members themselves doesn't have this problem:

(objBox.*(*i))( params );   //  If objBox is an object
(ptrBox->*(*i))( params );  //  If ptrBox is a pointer

(I don't think you need the parentheses around the *i, but the pointer to member syntax is already special enough.)

Madame answered 11/2, 2013 at 14:59 Comment(0)
P
10

From my "award winning" ;-) answer about delegates (available at https://mcmap.net/q/137739/-what-is-a-c-delegate/9568226#9568226) :

Typedef the pointer to member function like this:

typedef void (T::*fn)( int anArg );

Declare one like this:

fn functionPtr = &MyClass::MyFunction

Call it like this:

(MyObject.*functionPtr)( argument );
Philately answered 11/2, 2013 at 15:0 Comment(0)
C
1

Your attempt to get a member function pointer through an object betrays a misunderstanding. Member function pointers do not include a pointer to the object you call them on. You have to provide such a pointer at the point of the call.

As many have pointed out, the syntax for a member function call is either:

 obj.*funcptr(args);

or

 objptr->*funcptr(args);

In the example you've given, it sounds like what you really need is a virtual function. You have a standard operation (detecting wether or not an object intersects with a box) that needs to be called on many different types of objects, the type of which can't be known at compile time. This is a job that is cut out for virtual functions.

Conjunctiva answered 11/2, 2013 at 15:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.