By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,490 Members | 1,398 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,490 IT Pros & Developers. It's quick & easy.

Member function pointer woes

P: n/a
Hi,

I need to pass a pointer-to-member-function as a parameter to a function
which takes pointer-to-function as an argument. Is there any way to do it
besides overloading the function?

Here is a small program I wrote to check if I could get the address of the
function from the member-function-pointer, so that I could pass it to the
function as a normal function-pointer.

---------------------------------------------------
#include<stdio.h>

class classname{
public:
int add(int a, int b){
printf("inside add. \ta = %d, b = %d\n", a,b);
return a+b;
}
}obj;
typedef int(classname::*mfptr)(int, int);
typedef int (*fptr)(int, int);
main(){

mfptr mem_func_ptr;
fptr func_ptr;

mem_func_ptr = &classname::add;
func_ptr = (fptr)(&classname::add);

printf("&classname::add is %llx\n", &classname::add);
printf("&classname::add is %llx\n", &classname::add);

printf("mem_func_ptr is %llx\n", mem_func_ptr);
printf("func_ptr is %x\n\n", func_ptr);

printf("add called with func_ptr. sum is %d\n\n", func_ptr(2,3));
printf("add called with mem_func_fptr. sum is %d\n\n",
(obj.*mem_func_ptr)(2,3));
}

-----------------------------------------------------
I compiled it with the -Wno-pmf-conversions option. Here is the output of
the program:

------------------------------------------
&classname::add is ffbeee78ff23e5d0
&classname::add is ffbeee78ff243a4c

mem_func_ptr is ffbeee78ff243a4c
func_ptr is 109bc

inside add. a = 3, b = 68028
add called with func_ptr. sum is 68031

inside add. a = 2, b = 3
add called with mem_func_fptr. sum is 5

------------------------------------------
A few questions:

1. Why is the value of '&classname::add' in the two lines different?
2. Why does the value of parameter 'b' change when 'classname::add' is
called with 'func_ptr'?
3. If this approach is not correct, then could you please advise as to how
to go about with it?

Thanks.

Albert.
Jul 22 '05 #1
Share this Question
Share on Google+
15 Replies


P: n/a

"Albert" <al****@iitg.ernet.in> wrote in message
news:e9*************************@posting.google.co m...
Hi,

I need to pass a pointer-to-member-function as a parameter to a function
which takes pointer-to-function as an argument. Is there any way to do it
besides overloading the function?
No.

[snip]
3. If this approach is not correct, then could you please advise as to how
to go about with it?


Write a normal function which calls your member function and then pass the
normal function as a parameter.

john
Jul 22 '05 #2

P: n/a
Albert wrote:
Hi,

I need to pass a pointer-to-member-function as a parameter to a
function which takes pointer-to-function as an argument. Is there any
way to do it besides overloading the function?

<snipped>

3. If this approach is not correct, then could you please advise as
to how to go about with it?


I would advise you to consider using the Boost.Function library.
http://www.boost.org/doc/html/function.html

I have used it to have a library function which can take pointer-to-function
or pointer-to-member-function in different programs.

Mark
Jul 22 '05 #3

P: n/a
"Albert" <al****@iitg.ernet.in> skrev i meddelandet
news:e9*************************@posting.google.co m...
I need to pass a pointer-to-member-function as a parameter to a function
which takes pointer-to-function as an argument. Is there any way to do it
besides overloading the function?

You could use a templated version of the subscriber/publisher pattern. The
implementation isn't pretty, but the usage is kind of neat IMHO;-) Note that
SubscriberBase and Subscriber can be reused for other notifications of the
same type (for any class), in this case member functions that take an int
and return void.

// Base class for Subscriber. Must be a non-template since we
// need to store a pointer to an instance.
class SubscriberBase
{
public:
virtual void exec(int) = 0;
};

// The actual Subscriber class template. Stores a pointer to an object and a
pointer
// to one of it's member functions.
template<class T> class Subscriber : public SubscriberBase
{
private:
typedef void (T::*EventFunc)(int);
T *target; // Pointer to the object to recieve notification
EventFunc func; // Pointer to member function to be called
public:
Subscriber(T *target, EventFunc func) : func(func), target(target) { }
virtual void exec(int param) { (target->*func)(param); }
};

// And this is how it's used.
// Class that does stuff and notifies another object about something...
class Publisher
{
protected:
SubscriberBase *sub; // Could be a list really
public:
void registerSubscriber(SubscriberBase &s)
{
sub = &s;
};
void doSomething(int param)
{
// Do something
// ...
sub->exec(param); // ... and notify
}
};

// Test class. Recieves notifications.
class UserClass
{
public:
// Starts the the entire thing
void start()
{
// Publisher object that needs to tell this instance of UserClass about
something
Publisher test;

// Construct and register a subscriber object.
Subscriber<UserClass> sub(this, callback);
test.registerSubscriber(sub);

// Call a function that sends back notifications
test.doSomething(12345);
}

// Callback member function
void callback(int param)
{
cout << "Hello, " << param << endl;
}
};
Jul 22 '05 #4

P: n/a
On 29 Jun 2004 06:08:33 -0700, al****@iitg.ernet.in (Albert) wrote:
Hi,

I need to pass a pointer-to-member-function as a parameter to a function
which takes pointer-to-function as an argument. Is there any way to do it
besides overloading the function?

Here is a small program I wrote to check if I could get the address of the
function from the member-function-pointer, so that I could pass it to the
function as a normal function-pointer.

---------------------------------------------------
#include<stdio.h>
Better to use <iostream> and cout, cin etc. instead of printf()...
class classname{
public:
int add(int a, int b){
printf("inside add. \ta = %d, b = %d\n", a,b);
return a+b;
}
}obj; ^^^
What is that? Is this legal C++?
typedef int(classname::*mfptr)(int, int);
typedef int (*fptr)(int, int);
main(){
Always return int from main()...
mfptr mem_func_ptr;
fptr func_ptr;

mem_func_ptr = &classname::add;
func_ptr = (fptr)(&classname::add);
This cast will cause undefined behavior.

[snip]
3. If this approach is not correct, then could you please advise as to how
to go about with it?


As John said, create a normal (non-member) function which calls your
member function. However, you need to remember that you must pass an
object (or reference or pointer to an object) of your class in order
to call the member function.

--
Bob Hairgrove
No**********@Home.com
Jul 22 '05 #5

P: n/a
Bob Hairgrove wrote in news:c9********************************@4ax.com in
comp.lang.c++:
class classname{
public:
int add(int a, int b){
printf("inside add. \ta = %d, b = %d\n", a,b);
return a+b;
}
}obj;

^^^
What is that? Is this legal C++?


Yes its from C:

struct X
{
int x;
} x;

Same as:

struct X
{
int x;
};

struct X x; // in C and C++ and
X x; // C++ only.

This is why a semicolon is required after class/struct/union defenitions.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #6

P: n/a
Bob Hairgrove wrote:
On 29 Jun 2004 06:08:33 -0700, al****@iitg.ernet.in (Albert) wrote:
class classname{
public:
int add(int a, int b){
printf("inside add. \ta = %d, b = %d\n", a,b);
return a+b;
}
}obj;

^^^
What is that? Is this legal C++?


It is perfectly legal.

Mark
Jul 22 '05 #7

P: n/a
On 29 Jun 2004 15:42:34 GMT, Rob Williscroft <rt*@freenet.co.uk>
wrote:
Bob Hairgrove wrote in news:c9********************************@4ax.com in
comp.lang.c++:
class classname{
public:
int add(int a, int b){
printf("inside add. \ta = %d, b = %d\n", a,b);
return a+b;
}
}obj; ^^^
What is that? Is this legal C++?


Yes its from C:

struct X
{
int x;
} x;


No ... IF one uses this syntax in C++, it should be used like this:

typedef struct X
{
int x;
} x;

and not for classes.
Same as:

struct X
{
int x;
};

struct X x; // in C and C++ and
X x; // C++ only.

This is why a semicolon is required after class/struct/union defenitions.

Rob.


This syntax is not in the C++ standard ... although some compilers
might accept it, it is not standard C++ as far as I can tell.

Does that make it "legal"?
--
Bob Hairgrove
No**********@Home.com
Jul 22 '05 #8

P: n/a

"Bob Hairgrove" <wouldnt_you_like@to_know.com> wrote in message
news:nf********************************@4ax.com...
On 29 Jun 2004 15:42:34 GMT, Rob Williscroft <rt*@freenet.co.uk>
wrote:
Bob Hairgrove wrote in news:c9********************************@4ax.com in
comp.lang.c++:
class classname{
public:
int add(int a, int b){
printf("inside add. \ta = %d, b = %d\n", a,b);
return a+b;
}
}obj;
^^^
What is that? Is this legal C++?

Yes its from C:

struct X
{
int x;
} x;


No ... IF one uses this syntax in C++, it should be used like this:

typedef struct X
{
int x;
} x;

No, he was declaring an object of the classes, not a typedef. The sytax is
legal.
and not for classes. Yes it is.
Same as:

struct X
{
int x;
};

struct X x; // in C and C++ and
X x; // C++ only.

This is why a semicolon is required after class/struct/union defenitions.

Rob.
This syntax is not in the C++ standard ... although some compilers
might accept it, it is not standard C++ as far as I can tell.

Yes, it is standard and perfectly legal.

Does that make it "legal"?

moot point.
Jul 22 '05 #9

P: n/a
On Tue, 29 Jun 2004 15:05:01 -0400, "Xenos"
<do**********@spamhate.com> wrote:

[snip]
Yes, it is standard and perfectly legal.

[snip]

Well, I'm always willing to learn something new ... can you quote me
chapter and verse where this is written in the standard? I looked all
over, but did not find it.

(BTW, which is the "real" class name afterwards, X or obj)?

Thanks.

--
Bob Hairgrove
No**********@Home.com
Jul 22 '05 #10

P: n/a
Bob Hairgrove wrote in news:c1********************************@4ax.com in
comp.lang.c++:
On Tue, 29 Jun 2004 15:05:01 -0400, "Xenos"
<do**********@spamhate.com> wrote:

[snip]
Yes, it is standard and perfectly legal. [snip]

Well, I'm always willing to learn something new ... can you quote me
chapter and verse where this is written in the standard? I looked all
over, but did not find it.


Its quite hard to find, you need to chase down all the gramma
defenition's, search for "class-specifier" and "type-specifier".

Possibly you might want to start with the gramma summery in
appendix A (A.6 declaration's and A.8 classes).

In essence ( substitute ... with something leagal :) :

class X { ... } /* no semicolon */

is a class-specifier, which is also a type-specifier,
which is also a decl-specifier, which is the first part of
a simple-declaration.

The second part of a simple-declaration is the declarator,
i.e the thing being declared.

class X { ... } obj;

This declares the type 'X' and an instance of type 'X' 'obj'.

However 7/2 gives permission to omit the declarator in this
case (as X is also being declared), so in fact it is:

class X { ... };

Which is the exception to the rule.

(BTW, which is the "real" class name afterwards, X or obj)?


obj is not a type name its an instance of type classname (from
the OP's post).

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #11

P: n/a

"Bob Hairgrove" <wouldnt_you_like@to_know.com> wrote in message
news:c1********************************@4ax.com...
On Tue, 29 Jun 2004 15:05:01 -0400, "Xenos"
<do**********@spamhate.com> wrote:

[snip]
Yes, it is standard and perfectly legal. [snip]

Well, I'm always willing to learn something new ... can you quote me
chapter and verse where this is written in the standard? I looked all
over, but did not find it.

For which part, the way he created the object or the different ways he used
the class name?

Do I really need to dig out the standard??? I *really* believe that these
are not syntatically correct???

struct X {
int x;
} obj;

struct X obj2;
X obj3;

Or did *I* misunderstand what he wrote?

(BTW, which is the "real" class name afterwards, X or obj)?

X is the class name. obj is an object of the class.

Jul 22 '05 #12

P: n/a

"Xenos" <do**********@spamhate.com> wrote in message
news:cb*********@cui1.lmms.lmco.com...
Do I really need to dig out the standard??? I *really* believe that these
are not syntatically correct???


Sorry. Replace "I" in the second sentence to "Do you."

Jul 22 '05 #13

P: n/a
On 29 Jun 2004 20:19:39 GMT, Rob Williscroft <rt*@freenet.co.uk>
wrote:

[snip lots of patient explanation]
class X { ... } obj;

This declares the type 'X' and an instance of type 'X' 'obj'.

However 7/2 gives permission to omit the declarator in this
case (as X is also being declared), so in fact it is:

class X { ... };

Which is the exception to the rule.

(BTW, which is the "real" class name afterwards, X or obj)?


obj is not a type name its an instance of type classname (from
the OP's post).


Thanks very much for your patience ... I totally screwed up here,
missing "obj" for the instance name!

That's what happens after you have been indoctrinated for 10+ years to
always separate the class declaration from the implementation.

--
Bob Hairgrove
No**********@Home.com
Jul 22 '05 #14

P: n/a
On Tue, 29 Jun 2004 16:07:48 -0400, "Xenos"
<do**********@spamhate.com> wrote:

"Bob Hairgrove" <wouldnt_you_like@to_know.com> wrote in message
news:c1********************************@4ax.com.. .
On Tue, 29 Jun 2004 15:05:01 -0400, "Xenos"
<do**********@spamhate.com> wrote:

[snip]
>Yes, it is standard and perfectly legal.

[snip]

Well, I'm always willing to learn something new ... can you quote me
chapter and verse where this is written in the standard? I looked all
over, but did not find it.

For which part, the way he created the object or the different ways he used
the class name?

[snip]

I totally missed the fact that he was *creating an instance* of his
class immediately after the class declaration (see my post to Rob W.
for more...).

Sorry for the FUD.

--
Bob Hairgrove
No**********@Home.com
Jul 22 '05 #15

P: n/a
PKH

"Albert" <al****@iitg.ernet.in> wrote in message
news:e9*************************@posting.google.co m...
Hi,

I need to pass a pointer-to-member-function as a parameter to a function
which takes pointer-to-function as an argument. Is there any way to do it
besides overloading the function?

Here is a small program I wrote to check if I could get the address of the
function from the member-function-pointer, so that I could pass it to the
function as a normal function-pointer.

---------------------------------------------------
#include<stdio.h>

class classname{
public:
int add(int a, int b){
printf("inside add. \ta = %d, b = %d\n", a,b);
return a+b;
}
}obj;
typedef int(classname::*mfptr)(int, int);
typedef int (*fptr)(int, int);
main(){

mfptr mem_func_ptr;
fptr func_ptr;

mem_func_ptr = &classname::add;
func_ptr = (fptr)(&classname::add);

printf("&classname::add is %llx\n", &classname::add);
printf("&classname::add is %llx\n", &classname::add);

printf("mem_func_ptr is %llx\n", mem_func_ptr);
printf("func_ptr is %x\n\n", func_ptr);

printf("add called with func_ptr. sum is %d\n\n", func_ptr(2,3));
printf("add called with mem_func_fptr. sum is %d\n\n",
(obj.*mem_func_ptr)(2,3));
}

-----------------------------------------------------
I compiled it with the -Wno-pmf-conversions option. Here is the output of
the program:

------------------------------------------
&classname::add is ffbeee78ff23e5d0
&classname::add is ffbeee78ff243a4c

mem_func_ptr is ffbeee78ff243a4c
func_ptr is 109bc

inside add. a = 3, b = 68028
add called with func_ptr. sum is 68031

inside add. a = 2, b = 3
add called with mem_func_fptr. sum is 5

------------------------------------------
A few questions:

1. Why is the value of '&classname::add' in the two lines different?
If the code you show is actually the one running, I find this very strange
since
as far as I can tell, the codelines for your 2 print-statements are
identical.
2. Why does the value of parameter 'b' change when 'classname::add' is
called with 'func_ptr'?
I believe all memberfunctions have a hidden 'this' parameter. When you're
calling
a memberfunction as a regular function, the 'this' parameter is not added to
the stack
and you will get undefined behaviour.
3. If this approach is not correct, then could you please advise as to how
to go about with it?


It's hard to make recommodations withouth knowing much about how it is going
to be used,
but I think I would stay with either just regular function-pointers or just
memberfunction-pointers.
You can do much fun stuff with memberfunction-pointers, like passing
different virtual memberfunctions
as parameters to other memberfunctions.

PKH
Jul 22 '05 #16

This discussion thread is closed

Replies have been disabled for this discussion.