• Advertisement
Sign in to follow this  

A problem about a pointer to member function?

This topic is 1961 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

L have declare two function like this:

[source lang="cpp"]void order( void (*visit) (int,int) );
void visit(int,int);[/source]

They are member function in the same class?
And l want call order like this:

[source lang="cpp"]oder(visit);[/source]

but it can't pass.
How can l do this?

Share this post


Link to post
Share on other sites
Advertisement
You're using a regular pointer-to-function, not a pointer-to-member-function.
The syntax for pointer-to-member-functions looks like:

class Foo
{
public:
void order( void (Foo::*visit) (int,int) )
{
(this->*visit)(1,2);
}
void visit(int x, int y)
{
printf("%d, %d\n", x, y);
}
void test()
{
order(&Foo::visit);
}
};

Share this post


Link to post
Share on other sites
That's the syntax for calling a pointer-to-member-function.

It's a bit confusing because you've called both a variable and a function "visit", so I'll pretend the [font=courier new,courier,monospace]order[/font] definition is instead:
[font=courier new,courier,monospace]void order( void (Foo::*fn) (int,int) )[/font]

"[font=courier new,courier,monospace]fn[/font]" is a pointer, so "[font=courier new,courier,monospace]*fn[/font]" dereferences that pointer as usual. [font=courier new,courier,monospace]fn[/font] was a pointer-to-member-function, so [font=courier new,courier,monospace]*fn[/font] is just a member-function.
i.e. [font=courier new,courier,monospace]fn[/font] is "[font=courier new,courier,monospace]&Foo::visit[/font]" and [font=courier new,courier,monospace]*fn[/font] is "[font=courier new,courier,monospace]Foo::visit[/font]"

"[font=courier new,courier,monospace]object->[/font]" is the regular syntax for accessing members of an object.
Normally you don't have to write "[font=courier new,courier,monospace]this->[/font]" in front of members, but you can if you want to -- e.g. in [font=courier new,courier,monospace]test[/font] you could write "[font=courier new,courier,monospace]this->order(blah);[/font]" and it would mean the same as "[font=courier new,courier,monospace]order(blah);[/font]".

So going off the above, [font=courier new,courier,monospace](this-> *fn)[/font] ends up meaning [font=courier new,courier,monospace]this->visit[/font], which is the same as just saying [font=courier new,courier,monospace]visit[/font].
We need to wrap it in parenthesis ([font=courier new,courier,monospace]()[/font]) and have to include the "[font=courier new,courier,monospace]this->[/font]" because of the weird way that pointer-to-member-function syntax works ;)

So then, [font=courier new,courier,monospace](this-> *fn)(1, 2)[/font] is the same as [font=courier new,courier,monospace]visit(1,2)[/font], which ends up printing "[font=courier new,courier,monospace]1 2[/font]".

[edit]As wqking corrected below "[font=courier new,courier,monospace]-> *[/font]" shouldn't have a space in it and should be "[font=courier new,courier,monospace]->*[/font]" Edited by Hodgman

Share this post


Link to post
Share on other sites

So going off the above, [font=courier new,courier,monospace](this-> *fn)[/font] ends up meaning [font=courier new,courier,monospace]this->visit[/font], which is the same as just saying [font=courier new,courier,monospace]visit[/font].


I think -> * should be ->* because it's a single operator and we can even overload it.

OP, try to Google for "c++ pointer to member operator", no quote mark.
Here are some search results,
http://msdn.microsoft.com/en-us/library/k8336763%28v=vs.80%29.aspx
http://stackoverflow.com/questions/6586205/what-are-the-pointer-to-member-and-operators-in-c

And Hodgman's reply. :-)

Share this post


Link to post
Share on other sites
You are probably much better off learning about 'Interfaces' to solve this problem if you are going to use a pointer-to-a-member-function to solve it.


class ITweakable
{
public:
void TweakMe(void) = 0;
}

class Tweakie : ITweakable, IThwackable, //etc...
{
public:
void TweakMe(void)
{
g_Audio->StartPlayback('giggle.ogg');
}
void ThwackMe(void)
{
g_Audio->StartPlayback('oouff.ogg');
}
}

class TweakHerder
{
public:
AddTweakie(ITweakable* tweakie)
{
this->myTweakies.push_back(tweakie);
}
void TimeToTickleTheTweakies(void)
{
//Not C++ because C++ syntax for this is dog-pile
foreach(ITweakable* tweakie in myTweakies)
{
tweakie->TweakMe();
}
}
private:
list<ITweakable> myTweakies;
}


And there ya' go, entertainment for a toddler for hours.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement