Address of member function: problem

P

Paul Jansen

Don't go away yet... this is a bit more complicated than 'how do I
take a method address'!

I have a class foo, and method foo::bar. I also have a tree of foo
objects, which I process recursively, in top-down or bottom-up passes.
When I traverse the tree and reach object X, I need to call X.bar().
'bar' is not static; it needs the data in the current object/node.

Furthermore, I have generic (recursive) functions to traverse the
tree. The generic function has a parameter, which is the name of the
object method to call when the generic function reaches a particular
node in the tree. So, if I want to do a top-down pass through the
tree, calling 'bar' at every node, I say:

topDownPass(&foo::bar);

And 'topDownPass' does something like this:

void foo:topDownPass(NodeFunction nfunc) {
(this->*nfunc)();
...
}

This code compiles and links Ok (on gcc), but I don't understand it
(and I haven't tested it yet). 'bar' is not static. Which 'bar' am I
taking the address of in the call 'topDownPass(&foo::bar)'? Does it
matter, since there is presumably only one instance of 'bar' anyway?
What will 'this' be inside 'bar'?

Or should I make 'bar' static, and pass in 'this' as a parameter?

Thanks -

/PJ
 
O

Ondra Holub

Paul Jansen napsal:
Don't go away yet... this is a bit more complicated than 'how do I
take a method address'!

I have a class foo, and method foo::bar. I also have a tree of foo
objects, which I process recursively, in top-down or bottom-up passes.
When I traverse the tree and reach object X, I need to call X.bar().
'bar' is not static; it needs the data in the current object/node.

Furthermore, I have generic (recursive) functions to traverse the
tree. The generic function has a parameter, which is the name of the
object method to call when the generic function reaches a particular
node in the tree. So, if I want to do a top-down pass through the
tree, calling 'bar' at every node, I say:

topDownPass(&foo::bar);

And 'topDownPass' does something like this:

void foo:topDownPass(NodeFunction nfunc) {
(this->*nfunc)();
...
}

This code compiles and links Ok (on gcc), but I don't understand it
(and I haven't tested it yet). 'bar' is not static. Which 'bar' am I
taking the address of in the call 'topDownPass(&foo::bar)'?

If you have more instances of 1 class, its methods still exist only
once. So address of method is the same for all instances.
What will 'this' be inside 'bar'?

&foo::bar is pointer of special type. You cannot call method via such
pointer without instance (because it has access to instance data and to
table of virtual methods).
 
R

Rolf Magnus

Paul said:
Don't go away yet... this is a bit more complicated than 'how do I
take a method address'!

I have a class foo, and method foo::bar. I also have a tree of foo
objects, which I process recursively, in top-down or bottom-up passes.
When I traverse the tree and reach object X, I need to call X.bar().
'bar' is not static; it needs the data in the current object/node.

Furthermore, I have generic (recursive) functions to traverse the
tree. The generic function has a parameter, which is the name of the
object method to call when the generic function reaches a particular
node in the tree. So, if I want to do a top-down pass through the
tree, calling 'bar' at every node, I say:

topDownPass(&foo::bar);

And 'topDownPass' does something like this:

void foo:topDownPass(NodeFunction nfunc) {
(this->*nfunc)();
...
}

This code compiles and links Ok (on gcc), but I don't understand it
(and I haven't tested it yet). 'bar' is not static. Which 'bar' am I
taking the address of in the call 'topDownPass(&foo::bar)'?

What do you mean "which 'bar'"? There is only one 'bar' in 'foo' (or are
there several overloads?).
Does it matter, since there is presumably only one instance of 'bar'
anyway? What will 'this' be inside 'bar'?

The same 'this' that it was called with. A member function is basically
called the same way through a pointer as it is without, just that you
dereference the pointer.

Object o;
o.function();
(o.*function_pointer)();

in both cases, the 'this' pointer in the function points to the object 'o'.
 
P

Paul Jansen

What do you mean "which 'bar'"? There is only one 'bar' in 'foo' (or are
there several overloads?).

Yes, there's only one 'bar', but there are lots of 'foo' objects. My
confusion is that the syntax '&foo::bar' appears to be taking the
address of a static 'bar' method, but 'bar' is not static.

To rephrase the problem: I'm taking bar's address as '&foo:bar', but
I'm calling it as
void foo:topDownPass(NodeFunction nfunc) {
(this->*nfunc)();
...
}

ie. I'm calling it for a real object. There seems to be a disconnect
here.

What I think I understand from Ondra's reply is that it doesn't
matter. When taking the address of a member method, you use the
'&class_name::method_name' syntax, and not
'&object_name::method_name'. You only need an object name when you're
actually *calling* the method.

Is that right?

Thanks -

/PJ
 
R

Rolf Magnus

Paul said:
What I think I understand from Ondra's reply is that it doesn't
matter. When taking the address of a member method, you use the
'&class_name::method_name' syntax, and not '&object_name::method_name'.
You only need an object name when you're actually *calling* the method.

Is that right?

Yes.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top