472,954 Members | 2,376 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,954 software developers and data experts.

Passing a pointer to member function as a parameter to another member function

Gurus,

I have the following implementation of a member function:

class A
{
// ...
virtual double func(double v);
void caller(int i, int j, double (* callee)(double));
void foo() {caller(1, 2, func);
}

The compiler told me there's a syntax error, because the pointer to a member
function is different from a pointer to a regular function.
That is, the func cannot be passed to caller. I checked the FAQ and in "[30]
Pointers to member functions", it says the pointers to a member function and
to a regular member function are different. Ok, then I tried to change it to
static, and it works because static member function is like a regular
function. But a static function cannot be virtual. So I have to use
something suggested in the FAQ[30] like this:

void caller(int i, int j, double (A::*callee)(double))
{
// ...
(this->*callee)(param);
}

Isn't this an awkard solution? My question is: why was the C++ designed like
this, couldn't there be a easy and convenient way to pass the pointer like
a regular function? All the functions are in the same class, shouldn't the
so-called encapsulation make it convenient? Or maybe it's due to my
misunderstanding and poor design?

Thanks.
Jul 19 '05 #1
5 9301
On Sun, 27 Jul 2003 20:56:36 -0400, "Newsgroup - Ann"
<ne******@yahoo.com> wrote:
Gurus,

I have the following implementation of a member function:

class A
{
// ...
virtual double func(double v);
void caller(int i, int j, double (* callee)(double));
void foo() {caller(1, 2, func);
}

The compiler told me there's a syntax error, because the pointer to a member
function is different from a pointer to a regular function.
Yes, this is because pointers to member function must be accompanied
by the object to which it refers.
That is, the func cannot be passed to caller. I checked the FAQ and in "[30]
Pointers to member functions", it says the pointers to a member function and
to a regular member function are different. Ok, then I tried to change it to
static, and it works because static member function is like a regular
function. But a static function cannot be virtual. So I have to use
something suggested in the FAQ[30] like this:

void caller(int i, int j, double (A::*callee)(double))
{
// ...
(this->*callee)(param);
}

Isn't this an awkard solution?
The solution, no. The syntax, yes :)
My question is: why was the C++ designed like
this, couldn't there be a easy and convenient way to pass the pointer like
a regular function?
This is a very convinent way when you know how to use it. Typedef is
your friend :

typedef void (MyClass::* MyFunction)(int i1, int i2);

Now 'MyFunction' is a pointer to a member function of MyClass which
returns void and takes to ints.

For your example :

typedef double (A:: *callee)(double);

void caller(int i, int j, callee c)
{
(this->c)( .. );
}

which is quite simpler.
All the functions are in the same class, shouldn't the
so-called encapsulation make it convenient?


This is irrelevant. How do you want the compiler to know to which
object this function reffers ? Would you like the compiler to default
to 'this' if no object was provided ? This would have no sense.

What's more, encapsulation has nothing to do with that. I see you
have some troubles understanding this concept since you seem a bit
harsh on that. Encapsulation hides information, that's it.
Jonathan

Jul 19 '05 #2
"Newsgroup - Ann" <ne******@yahoo.com> wrote in message
news:3f********@rcfnews.cs.umass.edu
Gurus,

I have the following implementation of a member function:

class A
{
// ...
virtual double func(double v);
void caller(int i, int j, double (* callee)(double));
void foo() {caller(1, 2, func);
}

The compiler told me there's a syntax error, because the pointer to a
member function is different from a pointer to a regular function.
That is, the func cannot be passed to caller. I checked the FAQ and
in "[30] Pointers to member functions", it says the pointers to a
member function and to a regular member function are different. Ok,
then I tried to change it to static, and it works because static
member function is like a regular function. But a static function
cannot be virtual. So I have to use something suggested in the
FAQ[30] like this:

void caller(int i, int j, double (A::*callee)(double))
{
// ...
(this->*callee)(param);
}

Isn't this an awkard solution? My question is: why was the C++
designed like this, couldn't there be a easy and convenient way to
pass the pointer like a regular function? All the functions are in
the same class, shouldn't the so-called encapsulation make it
convenient? Or maybe it's due to my misunderstanding and poor design?

Thanks.


Pointers to member functions are very flexible. They can be used by
other classes and at global (or namespace) scope (provided that they
are bound to an appropriate object in either case). Moreover, even
within the same class, a pointer to member function does not have to
use the member data of the current object. It can use the member data
of another object of the same class by using the other object's
"this" pointer.

To see why you have to use this->*callee rather than just callee,
suppose you have two objects, a1 and a2. Then each object might store
a pointer to the other A object, called otherAObjectPtr. In that
case, you would be allowed to call

otherAObjectPtr->*callee

so that the function would use the "this" pointer (and hence the
member data) from the other object rather than its own. It is because
of that flexibility that you need to be explicit that you want to use
the "this" pointer of the current object.
--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)
Jul 19 '05 #3

"Jonathan Mcdougall" <DE******************@yahoo.ca> wrote in message
news:vs********************************@4ax.com...
On Sun, 27 Jul 2003 20:56:36 -0400, "Newsgroup - Ann"
<ne******@yahoo.com> wrote:
Gurus,

I have the following implementation of a member function:

class A
{
// ...
virtual double func(double v);
void caller(int i, int j, double (* callee)(double));
void foo() {caller(1, 2, func);
}

The compiler told me there's a syntax error, because the pointer to a memberfunction is different from a pointer to a regular function.
Yes, this is because pointers to member function must be accompanied
by the object to which it refers.
That is, the func cannot be passed to caller. I checked the FAQ and in "[30]Pointers to member functions", it says the pointers to a member function andto a regular member function are different. Ok, then I tried to change it tostatic, and it works because static member function is like a regular
function. But a static function cannot be virtual. So I have to use
something suggested in the FAQ[30] like this:

void caller(int i, int j, double (A::*callee)(double))
{
// ...
(this->*callee)(param);
}

Isn't this an awkard solution?


The solution, no. The syntax, yes :)
My question is: why was the C++ designed like
this, couldn't there be a easy and convenient way to pass the pointer likea regular function?


This is a very convinent way when you know how to use it. Typedef is
your friend :

typedef void (MyClass::* MyFunction)(int i1, int i2);

Now 'MyFunction' is a pointer to a member function of MyClass which
returns void and takes to ints.

For your example :

typedef double (A:: *callee)(double);

void caller(int i, int j, callee c)
{
(this->c)( .. );
}

which is quite simpler.


yeah, I saw this kind of solution from the FAQ I mentioned at the beginning,
but I am more concerning about the
(this->*callee)(param) part. btw, shouldn't (this->c) be (this->*c)?
All the functions are in the same class, shouldn't the
so-called encapsulation make it convenient?
This is irrelevant. How do you want the compiler to know to which
object this function reffers ? Would you like the compiler to default
to 'this' if no object was provided ? This would have no sense.


Yes, the default 'this' was what I meant. Why not making any sense? The
member data are used in this way, why not the function?
What's more, encapsulation has nothing to do with that. I see you
have some troubles understanding this concept since you seem a bit
harsh on that. Encapsulation hides information, that's it. LOL


Jonathan

Jul 19 '05 #4
> To see why you have to use this->*callee rather than just callee,
suppose you have two objects, a1 and a2. Then each object might store
a pointer to the other A object, called otherAObjectPtr. In that
case, you would be allowed to call

otherAObjectPtr->*callee

so that the function would use the "this" pointer (and hence the
member data) from the other object rather than its own. It is because
of that flexibility that you need to be explicit that you want to use
the "this" pointer of the current object.

but the 'this' for the reference to its own _member data_ could be omitted,
why not the same for the _member function_?

--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)

Jul 19 '05 #5
"Newsgroup - Ann" <ne******@yahoo.com> wrote in message
news:3f**********@rcfnews.cs.umass.edu
To see why you have to use this->*callee rather than just callee,
suppose you have two objects, a1 and a2. Then each object might
store
a pointer to the other A object, called otherAObjectPtr. In that
case, you would be allowed to call

otherAObjectPtr->*callee

so that the function would use the "this" pointer (and hence the
member data) from the other object rather than its own. It is
because
of that flexibility that you need to be explicit that you want to
use
the "this" pointer of the current object.


but the 'this' for the reference to its own _member data_ could be
omitted, why not the same for the _member function_?

[Re-post after the first seemed to disappear]

Pointers to member functions have a rather complicated character. For
comparison, think about the following members:

1. Ordinary data members, e.g., an int called m.
2. Member functions, e.g., a function called foo

When you use m within a class, it is implicitly replaced by this->m. The
role of "this" is to identify the object to which m belongs.

When you use foo within a class, it it implicitly replaced by this->foo. The
role of "this" is *not* to identify the object to which foo belongs, because
foo is the same for all objects in the class and does not belong to
individual objects. Rather, "this" identifies the object that foo is to use
if it needs to access member data.

Now consider a pointer to a member function that is itself a data member of
the A class. Suppose that there are two objects, a1 and a2, and each stores
a pointer to a member function, called ptr. Suppose that the ptr value
stored by a1 points to A::foo(), whereas the ptr value stored by a2 points
to A::goo().

Now if an A object invokes ptr, there are two bindings to be made, not one.
These correspond to the two sorts of bindings discussed above for m and foo.

First, it must be decided which ptr value to use --- the ptr value stored in
a1, pointing to the function A::foo(), or the ptr value stored by a2,
pointing to the function A::goo(). Second, in either case, it must be
decided which member variables the member function should use, those from a1
or those from a2, e.g., should it use the m integer from a1 or the m integer
from a2. It is possible to mix and match, e.g., you could use the ptr value
stored in a2 (giving the function A::goo() ), yet have the member function
pointed to use the member data of a1.

If, within the scope of the A class, you type:

(this->*ptr)();

then you are indeed being forced to make one "this" explicit. But there is a
second "this" that is being supplied implicitly, just like it normally is.
What you type is implicitly converted to:

(this->*this->ptr)();

The explicit "this" on the left shows that you want the function to use the
member variables of the current object. The implicitly supplied "this" on
the right shows that you want to use the ptr value of the current object.
The general syntax is

(pObjectSupplyingMemberVariables->*pObjectToWhichPointerBelongs->ptr)();

The rules concerning when "this" must be explicit and when "this" is
supplied implicitly mean that the ptr variable is being treated like the m
int variable but not like the foo() function --- which makes sense because
ptr is a variable like m, not a function like foo.

Now, you might prefer that both "this" pointers were supplied implicitly. I
don't know what, if any, technical difficulties that might pose for compiler
writers. But I hope that I have persuaded you that there is an underlying
consistency in the current syntax.
--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)

Jul 19 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: kazack | last post by:
I am a little confused with code I am looking at. My c++ book does not go into passing a structure to a function so I pulled out a c book which does. and I do not understand the prototype verses...
5
by: Andy | last post by:
Hi Could someone clarify for me the method parameter passing concept? As I understand it, if you pass a variable without the "ref" syntax then it gets passed as a copy. If you pass a...
58
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
6
by: Ian Robertson | last post by:
I am trying to write a function that takes a reference to an object as its arguement. The object is created in another function and I am trying to pass the object to another function from within...
6
by: keepyourstupidspam | last post by:
Hi, I want to pass a function pointer that is a class member. This is the fn I want to pass the function pointer into: int Scheduler::Add(const unsigned long timeout, void* pFunction, void*...
17
by: Christopher Benson-Manica | last post by:
Does the following program exhibit undefined behavior? Specifically, does passing a struct by value cause undefined behavior if that struct has as a member a pointer that has been passed to...
3
by: dice | last post by:
Hi, In order to use an external api call that requires a function pointer I am currently creating static wrappers to call my objects functions. I want to re-jig this so I only need 1 static...
7
by: TS | last post by:
I was under the assumption that if you pass an object as a param to a method and inside that method this object is changed, the object will stay changed when returned from the method because the...
8
by: S. | last post by:
Hi all, Can someone please help me with this? I have the following struct: typedef struct { char *name; int age; } Student;
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
1
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.