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 

How can I get the address of a virtual member function?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Roy Yao
Guest





PostPosted: Sat Sep 27, 2003 9:59 am    Post subject: How can I get the address of a virtual member function? Reply with quote



Hello,

I need to pass a pointer to a
callback function to the lower
level modules. But the function
is thought to be a virtual member one.

How can I get the real address of
the virtual member function?

Best regards,
Roy


Back to top
Victor Bazarov
Guest





PostPosted: Sat Sep 27, 2003 2:18 pm    Post subject: Re: How can I get the address of a virtual member function? Reply with quote



"Roy Yao" <flyao (AT) 263 (DOT) net> wrote...
Quote:
I need to pass a pointer to a
callback function to the lower
level modules. But the function
is thought to be a virtual member one.

How can I get the real address of
the virtual member function?

There is no difference of getting the address
of a member function based on its virtuality.
The way the address is used will determine
which function is actually called. The syntax
for getting the address of a member is

& <class-name> :: <member-name>

for example:

struct A {
virtual int foo() { return 42; }
};

struct B : A {
int foo() { return 73; }
};

int main() {
B b;
A& a = b;
int (A::*amem)() = &A::foo; // take address
return (a.*amem)(); // use the address
}

(the program above should return 73 to the hosting
environment)

BTW, what problem are you encountering?

Victor



Back to top
Roy Yao
Guest





PostPosted: Sun Sep 28, 2003 1:33 am    Post subject: Re: How can I get the address of a virtual member function? Reply with quote



Hello, Victor,

Thanks at first.

The problem troubling me is that I must convert a virtual member function
pointer to a non-member function pointer in order that other modules can
call the virtual member function without an object( that is the "this"
pointer is not needed in my virtual member function).

Can you catch my idea?

Roy

"Victor Bazarov" <v.Abazarov (AT) attAbi (DOT) com> wrote

Quote:
"Roy Yao" <flyao (AT) 263 (DOT) net> wrote...
I need to pass a pointer to a
callback function to the lower
level modules. But the function
is thought to be a virtual member one.

How can I get the real address of
the virtual member function?

There is no difference of getting the address
of a member function based on its virtuality.
The way the address is used will determine
which function is actually called. The syntax
for getting the address of a member is

& <class-name> ::
for example:

struct A {
virtual int foo() { return 42; }
};

struct B : A {
int foo() { return 73; }
};

int main() {
B b;
A& a = b;
int (A::*amem)() = &A::foo; // take address
return (a.*amem)(); // use the address
}

(the program above should return 73 to the hosting
environment)

BTW, what problem are you encountering?

Victor





Back to top
Shane Beasley
Guest





PostPosted: Sun Sep 28, 2003 8:07 pm    Post subject: Re: How can I get the address of a virtual member function? Reply with quote

"Roy Yao" <flyao (AT) 263 (DOT) net> wrote


Quote:
The problem troubling me is that I must convert a virtual member function
pointer to a non-member function pointer

You cannot do this in C++.

Quote:
in order that other modules can
call the virtual member function without an object( that is the "this"
pointer is not needed in my virtual member function).

First, a member function which does not use the "this" pointer should
not be a member function (or, at least, it should be a static member
function). Second, all virtual function calls use the "this" pointer
to determine which implementation to call.

As such, you can do what you want by breaking up the virtual function
into a static member function and a virtual function which calls it:

class Base {
public:
virtual void f () = 0;
virtual ~Base ();
};

class Derived : public Base {
public:
static void do_f ();
void f () { do_f(); }
};

Then pass &Derived::do_f instead.

However, that's not how you'd normally deal with a properly-written
C-style callback API. Such an API would take a pointer to a function
and a pointer to data to be passed to that function:

typedef void *cb_data_t;
typedef void (*cb_func_t) (cb_data_t);
void do_callback (cb_func_t f, cb_data_t x); /* calls f(x) */

To this API, pass a pointer to an object and a pointer to either a
static member or a non-member function which calls the desired member
function on the object:

class MyClass {
public:
void f ();
};

void call_f (cb_data_t p) { static_cast<MyClass *>(p)->f(); }

int main () {
MyClass obj;
do_callback(call_f, &obj);
return 0;
}

Note that you have to be really careful when you do this with
inheritance:

class Base {
public:
virtual void f () = 0;
virtual ~Base ();
};

void call_f (cb_data_t p) { static_cast<Base *>(p)->f(); }

class Derived : public Base {
public:
virtual void f ();
};

int main () {
Derived obj;

// WRONG: call_f expects Base *; we're passing Derived *
do_callback(call_f, &obj);

// RIGHT: pass Base * as expected
do_callback(call_f, static_cast<Base *>(&obj));
return 0;
}

In theory, conversion of Derived * to void * to Base * is undefined.
In practice, it probably will work unless multiple or virtual
inheritance is used. In any case, I suggest that you not take any
chances -- convert to Base * before passing. If you don't like casts
(who does?), you can write a wrapper like this instead:

// guarantees that x is a Base *
void do_base_callback (cb_func_t f, Base *x) { do_callback(f, x); }

int main () {
Derived obj;
do_base_callback(call_f, &obj);
return 0;
}

- Shane

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) 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.