C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

calling a function pointer to member function

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
roli
Guest





PostPosted: Tue Aug 19, 2003 12:34 am    Post subject: calling a function pointer to member function Reply with quote



Hello to all C++-experts!

Iīve a problem calling a member function through a function pointer
that is defined inside the class which contains the functions to be
called.

See the code below which doesnīt compile.

class ClassA {
public:

bool (ClassA::*fp)();

ClassA()
{
fp = &ClassA::f1;
};

bool call_f()
{
return (this->*fp)();
}

bool f1()
{
printf("f1n");
fp = &ClassA::f2;
return true;
};

bool f2()
{
printf("f2n");
fp = &ClassA::f1;
return false;
};
};


int main(int argc, char** argv) {
ClassA a;

// calling method 1:
a.call_f(); // ok

// calling method 2:
ClassAMemberFunc mf = a.fp;
(a.*mf)(); // ok

// calling method 3:
(a->*fp)(); // compilation error
}


While the first two callint methods work, I get the following
compilation err for the third:

error: In function `int main(int, char**)':
error: `fp' undeclared (first use this function)
error: (Each undeclared identifier is reported only once for each
function it appears in.)

Thanks for any helpful comments in advance,
--Roli

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Mike Davis
Guest





PostPosted: Tue Aug 19, 2003 10:33 am    Post subject: Re: calling a function pointer to member function Reply with quote



Hi,

I'm not an expert, but I did find and fix some problems with the code
below. Two of them were minor, the third addresses the point at issue.


roli wrote:
[snip]

You need to include a header file for your printf statement below, so add:

#include <cstdio>

Quote:

class ClassA {
public:

bool (ClassA::*fp)();

ClassA()
{
fp = &ClassA::f1;
};

bool call_f()
{
return (this->*fp)();
}

bool f1()
{
printf("f1n");
fp = &ClassA::f2;
return true;
};

bool f2()
{
printf("f2n");
fp = &ClassA::f1;
return false;
};
};


int main(int argc, char** argv) {
ClassA a;

// calling method 1:
a.call_f(); // ok

// calling method 2:

ClassAMemberFunc below is not defined, so:

typedef bool (ClassA::*ClassAMemberFunc )();

Quote:
ClassAMemberFunc mf = a.fp;
(a.*mf)(); // ok

// calling method 3:
(a->*fp)(); // compilation error
}


While the first two callint methods work, I get the following
compilation err for the third:

error: In function `int main(int, char**)':
error: `fp' undeclared (first use this function)
error: (Each undeclared identifier is reported only once for each
function it appears in.)

This is the real problem. You just need to believe your compiler
messages. The ->* operator takes a pointer to a class object on the
left and a name of a pointer to a member function on the right. In this
program:

(1) a is not a pointer, but an object. You will need to specify a.* to
use the pointer to member function call syntax

(2) As your compiler says, fp *is* undeclared in this context. The only
fp in the program is a member variable of ClassA. To access the fp
variable for a, use a.fp. This expression will return a pointer to a
member function, but you still need an object or pointer to object of
type ClassA to which to apply the pointer-to-member-function.

(3) Combining (1) & (2), one alternative is
(a.*a.fp)();
which compiles and runs on VC++.NET and g++ 3.2.

Please let us know why you would want to do this? To me it seems like a
lot of work for something you can do more easily via your first method
(preserving encapsulation) or your second (which is operationally the
same, but is somewhat more readable.

Quote:

Thanks for any helpful comments in advance,
--Roli

Hope this helps, both in the

Regards,

Mike


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
nimaca2001@libero.it
Guest





PostPosted: Tue Aug 19, 2003 10:42 am    Post subject: Re: calling a function pointer to member function Reply with quote



On 18 Aug 2003 20:34:17 -0400, roli <csac4930 (AT) uibk (DOT) ac.at> wrote:

Quote:
int main(int argc, char** argv) {
ClassA a;

// calling method 1:
a.call_f(); // ok

// calling method 2:
ClassAMemberFunc mf = a.fp;
(a.*mf)(); // ok

// calling method 3:
(a->*fp)(); // compilation error
}



To make things work just substitute the mf used in calling method 2
with a.fp. The result is:

// calling method revisited 3:
(a.*a.fp)(); // ok

I see two problems with your calling method 3: first 'a' is not
a pointer, second a.fp is a pointer to member which is bound to no
object. You could use this pointer to member and access a member of
a different object. For example:

ClassA b ;

(b.(*a.fp))() ;

If you add this code at the end then you get this output

f1
f2
f1
f2

You get the f2 at the fourth line because the third call
makes a.fp point to f2, regardless the fact that the
just constructed b.fp points to f1.




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ben Hutchings
Guest





PostPosted: Tue Aug 19, 2003 12:37 pm    Post subject: Re: calling a function pointer to member function Reply with quote

In article <5cf7eba.0308181323.2bf4c50f (AT) posting (DOT) google.com>, roli wrote:
Quote:
Iīve a problem calling a member function through a function pointer
that is defined inside the class which contains the functions to be
called.

See the code below which doesnīt compile.

class ClassA {
public:

bool (ClassA::*fp)();
snip
};


int main(int argc, char** argv) {
ClassA a;
snip
// calling method 3:
(a->*fp)(); // compilation error
}


While the first two callint methods work, I get the following
compilation err for the third:

error: In function `int main(int, char**)':
error: `fp' undeclared (first use this function)
error: (Each undeclared identifier is reported only once for each
function it appears in.)

As it says, there's no fp variable in that function. The operands
of the built-in "->*" operator must be a pointer and a member
pointer, but neither of the operands you're using match those.

Possibly what you want is (a.*a.fp)();

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Nicola Musatti
Guest





PostPosted: Tue Aug 19, 2003 6:13 pm    Post subject: Re: calling a function pointer to member function Reply with quote

[email]csac4930 (AT) uibk (DOT) ac.at[/email] (roli) wrote in message
news:<5cf7eba.0308181323.2bf4c50f (AT) posting (DOT) google.com>...
[...]

Given:

Quote:
class ClassA {
public:
bool (ClassA::*fp)();

ClassA()
{
fp = &ClassA::f1;
};

bool f1()
{
printf("f1n");
return true;
};
};


int main(int argc, char** argv) {
ClassA a;
// calling method 3:
(a->*fp)(); // compilation error
}

The correct syntax for the call above is

(a.*(a.fp))();

fp is a non static member of ClassA, so you need an instance of ClassA
to refer to it.

Cheers,
Nicola Musatti

P.S. The next time please post a complete example. Yours lacks the
inclusion of <cstdio> and a definition of ClassAMemberFunc.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
roli
Guest





PostPosted: Wed Aug 20, 2003 11:51 pm    Post subject: Re: calling a function pointer to member function Reply with quote

Yes, you all are absolutly right.
Quote:
(a.*a.fp)();
Thatīs it.


As I realized later, that the code in my the posting was incomplete. I
forgot to
include the #include <cstdio>
and the
typedef bool (ClassA::*ClassAMemberFunc)();

Sorry for that.

Some of you also asked for the reason why I would like to use the
third
calling method (a.*a.fp)() :

I didnīt want to use

// calling method 1:
a.call_f();

simply because I wanted to save execution time by avoiding the extra
function call. I my code I will have to call *a.fp very often and Iīm
writing
a somewhat time critical aplicaiton.

For

// calling method 2:
ClassAMemberFunc mf = a.fp;
(a.*mf)();

the user of the ClassA would have to define a function pointer and
initialize it correctly. Thatīs not a good API, nor "user"-friendly.

In my program ClassA will contain the algorithm for walking through a
2
dimensional grid. The order walking throuhg the grid can be
complicated and
is dependent on some parameters. Therefor I would like to hide this
intelligence in ClassA and give the user of ClassA the possibility to
the
following

while( (a.*a.fp)(x,y) ) { do something in each cell };

or

while( a.call_f(x,y) ) { do something in each cell };

until each cell of the grid was touched in the right order. (I know
that
above fp was defined without the calling parameters int x, int y, but
in my application it will. )

If somebody has a better or other idea for applying such an interface
without
using function pointers, please tell me.

Now that I know the correct calling syntax for the third method I was
able
to test the performance between a.call_f(); and
(a.*a.fp)();
and realized that the time saved using the latter call is marginal in
relation to the operation between consecutive calls to a.call_f() or
(a.*a.fp)(). So I will use the a.call_f() in my application, because
it
provides the simplest API to ClassA and better preserves encapsulation
of
the implementation of ClassA.

Thanks for your time!

--Roli

PS: Further comments are highly appreciated!

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.