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

Address of virtual member function from object (*not* class)

P: n/a
Hi all!

Just out of curiosity: Is there any way to get the address of a
particular virtual member function given an object? Some code to make
things more clear...

class A
{
public:
A() { }
virtual void f() { }
};

class B: public A
{
public:
B() { }
virtual void f() { }
};

typedef void (A::*FPtr)();

FPtr getFAddress(A* obj)
{
return &obj->f; // FIXME This won't compile (at least on VC++ 8)
}

int main()
{
A a;
B b;

getFAddress(&a); // Should return &A::f
getFAddress(&b); // Should return &B::f
}
The "intuituve" solution of this implementation of getFAddress
doesn't even compile on VC++ 8 (error C2276 if that matters). Note
that f is virtual, so the address depends on the object's class. Now,
if the compiler can generate the code to get the address of the right
f member, why can't we use this for our own code? (OK, this may lead
to lots of catastrophic code -- like the end of polymorphism as we
know it, but anyway...). I don't really think there is a portable
solution for this, but if someone has had this problem before, I'm
curious to see their solution.

Thanks,

Gabriel
Sep 2 '08 #1
Share this Question
Share on Google+
11 Replies


P: n/a
cch
于 Tue, 02 Sep 2008 05:22:50 -0700,Gabriel de Dietrich写到:
Hi all!

Just out of curiosity: Is there any way to get the address of a
particular virtual member function given an object? Some code to make
things more clear...

class A
{
public:
A() { }
virtual void f() { }
};

class B: public A
{
public:
B() { }
virtual void f() { }
};

typedef void (A::*FPtr)();

FPtr getFAddress(A* obj)
{
return &obj->f; // FIXME This won't compile (at least on
VC++ 8)
}

int main()
{
A a;
B b;

getFAddress(&a); // Should return &A::f getFAddress
(&b); // Should
return &B::f
}
The "intuituve" solution of this implementation of getFAddress
doesn't even compile on VC++ 8 (error C2276 if that matters). Note that
f is virtual, so the address depends on the object's class. Now, if the
compiler can generate the code to get the address of the right f member,
why can't we use this for our own code? (OK, this may lead to lots of
catastrophic code -- like the end of polymorphism as we know it, but
anyway...). I don't really think there is a portable solution for this,
but if someone has had this problem before, I'm curious to see their
solution.

Thanks,

Gabriel
Is follow title suitable for you?

http://www.codeproject.com/KB/cpp/Im...pDelegate.aspx
--
cch@srdgame
Sep 2 '08 #2

P: n/a
Gabriel de Dietrich wrote:
Just out of curiosity: Is there any way to get the address of a
particular virtual member function given an object? Some code to make
things more clear...

class A
{
public:
A() { }
virtual void f() { }
};

class B: public A
{
public:
B() { }
virtual void f() { }
};

typedef void (A::*FPtr)();

FPtr getFAddress(A* obj)
{
return &obj->f; // FIXME This won't compile (at least on VC++ 8)
}

int main()
{
A a;
B b;

getFAddress(&a); // Should return &A::f
getFAddress(&b); // Should return &B::f
}
The "intuituve" solution of this implementation of getFAddress
doesn't even compile on VC++ 8 (error C2276 if that matters). Note
that f is virtual, so the address depends on the object's class. Now,
if the compiler can generate the code to get the address of the right
f member, why can't we use this for our own code? (OK, this may lead
to lots of catastrophic code -- like the end of polymorphism as we
know it, but anyway...).
The answer to your question is "because we don't need to". There are
many things that compiler can do that the program itself can't. For
example, I am quite certain in the compiler classes (the UDTs in our
programs) are objects. In our programs they are not...
I don't really think there is a portable
solution for this, but if someone has had this problem before, I'm
curious to see their solution.
"Curiosity" is not really a valid reason, I believe. So, really, why
would you want to do that? You're not using the pointer-to-member in
any way, so what would be the point of returning it?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 2 '08 #3

P: n/a
On Sep 2, 3:28*pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
"Curiosity" is not really a valid reason, I believe. *So, really, why
would you want to do that? *You're not using the pointer-to-member in
any way, so what would be the point of returning it?
Well, it is for me... :-)

To answer your question: Suppose you have an arbitrarily large
inheritance hierarchy with root class A, and you want to know if some
subclass reimplements f. If you know the class, no problem. Just test

&A::f == &B::f

or whatever other class, and it's done. Now, suppose you don't know
the class because all you have is a polymorphic pointer to an object
(like in "A* obj"). In this case you would test

&A::f == getFAddress(obj)

With my example code, this would be true if the class of *obj is A,
and false if it's B. Moreover, you don't know all the classes from the
inheritance hierarchy, so you can't (or don't want to) check your
object against all the classes using typeid, or dynamic_cast, or
whatever.

As for the final purpose of this, I don't have any. If you want to
know, it's just an idea I had when trying to deal with exceptions in
event handlers using the wxWidgets framework. But I've found a better
solution, at least more -- let's say -- natural.
Sep 2 '08 #4

P: n/a
On Sep 2, 3:11*pm, "cch@srdgame" <srdg...@gmail.comwrote:
Is follow title suitable for you?

http://www.codeproject.com/KB/cpp/Im...pDelegate.aspx
No, sorry. It's not really that. See my following post.

Thanks anyway.

Gabriel
Sep 2 '08 #5

P: n/a
Gabriel de Dietrich wrote:
On Sep 2, 3:28 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>"Curiosity" is not really a valid reason, I believe. So, really, why
would you want to do that? You're not using the pointer-to-member in
any way, so what would be the point of returning it?

Well, it is for me... :-)

To answer your question: Suppose you have an arbitrarily large
inheritance hierarchy with root class A, and you want to know if some
subclass reimplements f. If you know the class, no problem. Just test

&A::f == &B::f

or whatever other class, and it's done. Now, suppose you don't know
the class because all you have is a polymorphic pointer to an object
(like in "A* obj"). In this case you would test

&A::f == getFAddress(obj)

With my example code, this would be true if the class of *obj is A,
and false if it's B. Moreover, you don't know all the classes from the
inheritance hierarchy, so you can't (or don't want to) check your
object against all the classes using typeid, or dynamic_cast, or
whatever.

As for the final purpose of this, I don't have any. If you want to
know, it's just an idea I had when trying to deal with exceptions in
event handlers using the wxWidgets framework. But I've found a better
solution, at least more -- let's say -- natural.
You can use metaprogramming technique to query if a class implements f.

Fei
Sep 2 '08 #6

P: n/a
On Sep 2, 4:07 pm, Gabriel de Dietrich <gabriel.dedietr...@gmail.com>
wrote:
On Sep 2, 3:28 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
"Curiosity" is not really a valid reason, I believe. So, really, why
would you want to do that? You're not using the pointer-to-member in
any way, so what would be the point of returning it?
Well, it is for me... :-)
To answer your question: Suppose you have an arbitrarily large
inheritance hierarchy with root class A, and you want to know
if some subclass reimplements f. If you know the class, no
problem. Just test
&A::f == &B::f
or whatever other class, and it's done.
If I read the standard correctly, that test shoud always return
true (supposing that f is virtual, and that B derives from A).
Regardless of whether B overrides the function or not. (I'm not
100% sure about my reading of the standard here, however, since
both of the compilers available to me say that the comparison is
illegal.)

Pointers to members respect virtuality; a pointer to a virtual
function will "point" to the correct function in whatever object
it happens to be used with.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
Sep 2 '08 #7

P: n/a
Fei Liu wrote:
Gabriel de Dietrich wrote:
>On Sep 2, 3:28 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>>"Curiosity" is not really a valid reason, I believe. So, really, why
would you want to do that? You're not using the pointer-to-member in
any way, so what would be the point of returning it?

Well, it is for me... :-)

To answer your question: Suppose you have an arbitrarily large
inheritance hierarchy with root class A, and you want to know if some
subclass reimplements f. If you know the class, no problem. Just test

&A::f == &B::f

or whatever other class, and it's done. Now, suppose you don't know
the class because all you have is a polymorphic pointer to an object
(like in "A* obj"). In this case you would test

&A::f == getFAddress(obj)

With my example code, this would be true if the class of *obj is A,
and false if it's B. Moreover, you don't know all the classes from the
inheritance hierarchy, so you can't (or don't want to) check your
object against all the classes using typeid, or dynamic_cast, or
whatever.

As for the final purpose of this, I don't have any. If you want to
know, it's just an idea I had when trying to deal with exceptions in
event handlers using the wxWidgets framework. But I've found a better
solution, at least more -- let's say -- natural.
You can use metaprogramming technique to query if a class implements f.

Fei
Well, yes, but the point is that metaprogramming will only check with
the static type of the pointer, not with its dynamic. So, no go with
templates in this case...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 2 '08 #8

P: n/a
James Kanze wrote:
On Sep 2, 4:07 pm, Gabriel de Dietrich <gabriel.dedietr...@gmail.com>
wrote:
>On Sep 2, 3:28 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>>"Curiosity" is not really a valid reason, I believe. So, really, why
would you want to do that? You're not using the pointer-to-member in
any way, so what would be the point of returning it?
> Well, it is for me... :-)
>To answer your question: Suppose you have an arbitrarily large
inheritance hierarchy with root class A, and you want to know
if some subclass reimplements f. If you know the class, no
problem. Just test
> &A::f == &B::f
>or whatever other class, and it's done.

If I read the standard correctly, that test shoud always return
true (supposing that f is virtual, and that B derives from A).
Regardless of whether B overrides the function or not. (I'm not
100% sure about my reading of the standard here, however, since
both of the compilers available to me say that the comparison is
illegal.)

Pointers to members respect virtuality; a pointer to a virtual
function will "point" to the correct function in whatever object
it happens to be used with.
Yes, but, again, how would he get a pointer to member from a pointer to
an object (possibly of the derived type)? Would 'typeid' help?
Probalby not. IOW, what does one need to put on line 6

class B { public: virtual void foo() {} };
class D1 : public B { void foo() {} };
class D2 : public B { }; // no overrider for 'foo'

bool bar(B* pB) {
return ??? ; // (line 6)
}

#include <iostream>
#include <ostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main() {
srand(unsigned(time(0)));
D1 d1;
D2 d2;
for (int i = 0; i < 10; ++i) {
cout << "attempt " << i;
B* pB = &d2;
if (rand() & 1)
pB = &d1;
cout << (bar(pB) ? " :-)" : "");
cout << endl;
}
}

to see intermittent smileys?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 2 '08 #9

P: n/a
On Sep 2, 6:46 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
Fei Liu wrote:
[...]
You can use metaprogramming technique to query if a class implements f.
Well, yes, but the point is that metaprogramming will only check with
the static type of the pointer, not with its dynamic. So, no go with
templates in this case...
Actually, you can't use metaprogramming to query what the
original poster wanted, even on statically known types.
Metaprogramming can query whether a class has a function f, but
it can't distinguish whether that function is present because the
class implemented it directly, or because it inherited it from a
base class.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
Sep 3 '08 #10

P: n/a
On Sep 2, 7:02 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
James Kanze wrote:
On Sep 2, 4:07 pm, Gabriel de Dietrich <gabriel.dedietr...@gmail.com>
wrote:
On Sep 2, 3:28 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>"Curiosity" is not really a valid reason, I believe. So, really, why
would you want to do that? You're not using the pointer-to-member in
any way, so what would be the point of returning it?
Well, it is for me... :-)
To answer your question: Suppose you have an arbitrarily large
inheritance hierarchy with root class A, and you want to know
if some subclass reimplements f. If you know the class, no
problem. Just test
&A::f == &B::f
or whatever other class, and it's done.
If I read the standard correctly, that test shoud always return
true (supposing that f is virtual, and that B derives from A).
Regardless of whether B overrides the function or not. (I'm not
100% sure about my reading of the standard here, however, since
both of the compilers available to me say that the comparison is
illegal.)
Pointers to members respect virtuality; a pointer to a virtual
function will "point" to the correct function in whatever object
it happens to be used with.
Yes, but, again, how would he get a pointer to member from a
pointer to an object (possibly of the derived type)?
You can't. Generally speaking, pointer to member is a static
concept (since pointers to members exist in the absense of any
actual object).
Would 'typeid' help?
Not the standard typeid, anyway. An implementation could extend
it so that it did (say by adding a function to std::type_info
which returned a reference to a _Class---an implementation
defined class along the lines of Java's java.lang.Class), but I
don't know of any which do. (As far as I know, the demand for
it is quite low. When I used Java, except for a few limited
uses which are easily implemented differently---and more
safely---in C++, the only use I found for it was for some
generic test programs of data containers.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
Sep 3 '08 #11

P: n/a
So, it seems that Old Bjarne didn't want any of us to inspect the
innards of classes and objects. (Like class meta-programming in, e.g.,
Python). That leaves us with hacking around the vtable as the only
solution. Well, I'm a bit less curious about that... (OK, I did
inspect the assembly code generated by VC++, only to learn that it was
less than obvious how to guess the entry number in the vtable for a
given method).

Thank you all for the replies. I've learned a couple of interesting
things.

Gabriel
Sep 3 '08 #12

This discussion thread is closed

Replies have been disabled for this discussion.