 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Roy Yao Guest
|
Posted: Sat Sep 27, 2003 9:59 am Post subject: How can I get the address of a virtual member function? |
|
|
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
|
Posted: Sat Sep 27, 2003 2:18 pm Post subject: Re: How can I get the address of a virtual member function? |
|
|
"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
|
Posted: Sun Sep 28, 2003 1:33 am Post subject: Re: How can I get the address of a virtual member function? |
|
|
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
|
Posted: Sun Sep 28, 2003 8:07 pm Post subject: Re: How can I get the address of a virtual member function? |
|
|
"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 |
|
 |
|
|
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
|
|