www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - get Class from Pointer of member

reply "StefanvT" <stefanvt gmx.de> writes:
Hi,
I'm totally new to D. But it looks very interesting :-)
I normally develop in C++.

I have such a function in C++:

template<class CB,class FIELD>
inline CB* get_class_from_field( FIELD CB::*field, FIELD* mp) {
     return reinterpret_cast<CB*>(
             reinterpret_cast<char*>(mp) -
             
reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<CB*>(0)->*field)));
}


Here I come with a pointer to a class member and can calculate 
the pointer to the class, where the member is within. (Nothing 
spectacular in c++)

Is this also possible in D?
I noticed that it's not very easy to get a member pointer on the 
heap. Isn't it?

thank you & best regards,
Stefan
May 24 2012
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 05/24/2012 05:29 AM, StefanvT wrote:

 I have such a function in C++:

 template<class CB,class FIELD>
 inline CB* get_class_from_field( FIELD CB::*field, FIELD* mp) {
 return reinterpret_cast<CB*>(
 reinterpret_cast<char*>(mp) -
 reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<CB*>(0)->*field)));
 }
I think get_object_from_field() would be a better name.
 Here I come with a pointer to a class member and can calculate the
 pointer to the class, where the member is within. (Nothing spectacular
 in c++)

 Is this also possible in D?
There are no pointers to members in D. In C++, member pointers carry the offset of the field. The same can be achieved by using the .offsetof property: class C { int i; int j; } CB get_object_from_field(CB, FIELD)(size_t offset, FIELD * f) { return cast(CB)(cast(ubyte*)f - offset); } void main() { auto c = new C; C c2 = get_object_from_field!C(c.j.offsetof, &c.j); assert(c2 is c); } I am pretty sure there are better solutions for a more specific problem. Ali -- D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
May 24 2012
parent reply "StefanvT" <stefanvt gmx.de> writes:
Hey thank you!! :-)

I already tried to use offsetof on my own. But I always try to
cast to a pointer.
And this fails horribly :o)

So thank you. I think I need to have a deeper look at references
and pointer in D!
May 24 2012
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 05/24/2012 10:25 AM, StefanvT wrote:
 Hey thank you!! :-)

 I already tried to use offsetof on my own. But I always try to
 cast to a pointer.
 And this fails horribly :o)

 So thank you. I think I need to have a deeper look at references
 and pointer in D!
I should have mentioned that pointers to member functions are possible in D as delegates. A delegate keeps the object that it is bound to alive: import std.stdio; class C { int i; void foo() { writeln("Called on object at ", &i); } } alias void delegate() MemberFunc; MemberFunc return_object_delegate() { auto c = new C; c.foo(); auto d = &c.foo; // c will be kept alive return d; } void main() { auto d = return_object_delegate(); // ... some time later d(); } Ali -- D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
May 24 2012