Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > about pointers on class' members

Reply
Thread Tools

about pointers on class' members

 
 
Chameleon
Guest
Posts: n/a
 
      12-22-2009
We have this structure:
-----------------------
struct A {
struct B {
...
} b;

...

struct C {
void no_way_dude();
} c;
};
-----------------------

How can I have access on 'b' from inside of 'no_way_dude()'?
I mean without pass parameters to 'C()' or to 'no_way_dude()'
You can use 'friend' as you wish.

Until now I use:
B &b = *(B*)(((char*) this) - sizeof(B));
But it is totally lame.
If I add a definition between B and C, it will screwed.


Basically I need something like:
off_t rel = (char*) A::C - (char*) A::B;

Any workaround without pass pointers to functions?
 
Reply With Quote
 
 
 
 
Gert-Jan de Vos
Guest
Posts: n/a
 
      12-22-2009
On Dec 22, 1:51*pm, Chameleon <(E-Mail Removed)> wrote:
> We have this structure:
> -----------------------
> struct A {
> * * * * struct B {
> * * * * ...
> * * * * } b;
>
> * * * * ...
>
> * * * * struct C {
> * * * * * * * * void no_way_dude();
> * * * * } c;};
>
> -----------------------
>
> How can I have access on 'b' from inside of 'no_way_dude()'?
> I mean without pass parameters to 'C()' or to 'no_way_dude()'


You can't since b and c are unrelated objects. The only relation
is that both are members of A. So, the only way to reach one from
the other is through an instance of A: a.b or a.c.

Both B and C objects can exist as stand-alone objects:

A::B A::GetB() const { return B(); }

So there can not be a way to reach one from the other.
 
Reply With Quote
 
 
 
 
Chameleon
Guest
Posts: n/a
 
      12-22-2009
στις 22 Δεκ 2009 15:32, O/H Gert-Jan de Vos *γραψε:
> On Dec 22, 1:51 pm, Chameleon<(E-Mail Removed)> wrote:
>> We have this structure:
>> -----------------------
>> struct A {
>> struct B {
>> ...
>> } b;
>>
>> ...
>>
>> struct C {
>> void no_way_dude();
>> } c;};
>>
>> -----------------------
>>
>> How can I have access on 'b' from inside of 'no_way_dude()'?
>> I mean without pass parameters to 'C()' or to 'no_way_dude()'

>
> You can't since b and c are unrelated objects. The only relation
> is that both are members of A. So, the only way to reach one from
> the other is through an instance of A: a.b or a.c.
>
> Both B and C objects can exist as stand-alone objects:
>
> A::B A::GetB() const { return B(); }
>
> So there can not be a way to reach one from the other.


void A::C::no_way_dude()
{
A *a = 0;
B &b = *(B*)(((char*) this) - (char*) &a->c - (char*) &a->b);
// DONE!!!
}
 
Reply With Quote
 
Michael Doubez
Guest
Posts: n/a
 
      12-22-2009
On 22 dc, 13:51, Chameleon <(E-Mail Removed)> wrote:
> We have this structure:
> -----------------------
> struct A {
> * * * * struct B {
> * * * * ...
> * * * * } b;
>
> * * * * ...
>
> * * * * struct C {
> * * * * * * * * void no_way_dude();
> * * * * } c;};
>
> -----------------------
>
> How can I have access on 'b' from inside of 'no_way_dude()'?
> I mean without pass parameters to 'C()' or to 'no_way_dude()'
> You can use 'friend' as you wish.
>
> Until now I use:
> B &b = *(B*)(((char*) this) - sizeof(B));
> But it is totally lame.
> If I add a definition between B and C, it will screwed.
>
> Basically I need something like:
> off_t rel = (char*) A::C - (char*) A::B;
>
> Any workaround without pass pointers to functions?


There is a solution but it is not practical with the current standard,
a little bit better with the next (I will explain latter): the trick
is to use the offsetof() macro.

struct A {
struct B {
...
} b;

...

struct C {
void no_way_dude()
{
B& my_b = owner().b;
}
private:
A& owner() {
return *reinterpret_cast<A*>(
reinterpret_cast<char*>(this) -
offsetof(A, c));
}

} c;
};

It has the drawback that it is not guaranteed by the current standard
if A is not a POD and in the next standard if A is not a /standard
layout/ class.

Which means that
- with the current standard, you have UB as soon as you define a
constructor or private/public areas.
- with the next standard, you have UB if you add virtual functions or
virtual inheritance.

Now in practice, compilers such as gcc and I think VC++ already
support the offsetof() macro with a simple class (without virtual
elements).

It is a risky trick and you may be better without it.

--
Michael
 
Reply With Quote
 
Jeff Flinn
Guest
Posts: n/a
 
      12-22-2009
Chameleon wrote:
> στις 22 Δεκ 2009 15:32, O/H Gert-Jan de Vos *γραψε:
>> On Dec 22, 1:51 pm, Chameleon<(E-Mail Removed)> wrote:
>>> We have this structure:
>>> -----------------------
>>> struct A {
>>> struct B {
>>> ...
>>> } b;
>>>
>>> ...
>>>
>>> struct C {
>>> void no_way_dude();
>>> } c;};
>>>
>>> -----------------------
>>>
>>> How can I have access on 'b' from inside of 'no_way_dude()'?
>>> I mean without pass parameters to 'C()' or to 'no_way_dude()'

>>
>> You can't since b and c are unrelated objects. The only relation
>> is that both are members of A. So, the only way to reach one from
>> the other is through an instance of A: a.b or a.c.
>>
>> Both B and C objects can exist as stand-alone objects:
>>
>> A::B A::GetB() const { return B(); }
>>
>> So there can not be a way to reach one from the other.

>
> void A::C::no_way_dude()
> {
> A *a = 0;
> B &b = *(B*)(((char*) this) - (char*) &a->c - (char*) &a->b);
> // DONE!!!
> }


And what happens when you or someone else tries the following weeks,
months or years later:

int main()
{
A:C c;

c.no_way_dude();

return 0;
}

You basically have a (very) bad design.

Jeff
 
Reply With Quote
 
Vladimir Jovic
Guest
Posts: n/a
 
      12-22-2009
Chameleon wrote:

[snip]
> void A::C::no_way_dude()
> {
> A *a = 0;
> B &b = *(B*)(((char*) this) - (char*) &a->c - (char*) &a->b);
> // DONE!!!
> }


Take a look at this:
http://www.google.de/#hl=en&source=h...c34adcbfaca52f


Why don't you move the no_way_dude() method from C to A? Then instead of
passing objects of type C, pass objects of type A
 
Reply With Quote
 
Michael Doubez
Guest
Posts: n/a
 
      12-22-2009
On 22 déc, 16:01, Jeff Flinn <(E-Mail Removed)> wrote:
> Chameleon wrote:
> > στις 22 Δεκ 2009 15:32, O/H Gert-Jan de Vos *γραψε:
> >> On Dec 22, 1:51 pm, Chameleon<(E-Mail Removed)> *wrote:
> >>> We have this structure:
> >>> -----------------------
> >>> struct A {
> >>> * * * * *struct B {
> >>> * * * * *...
> >>> * * * * *} b;

>
> >>> * * * * *...

>
> >>> * * * * *struct C {
> >>> * * * * * * * * *void no_way_dude();
> >>> * * * * *} c;};

>
> >>> -----------------------

>
> >>> How can I have access on 'b' from inside of 'no_way_dude()'?
> >>> I mean without pass parameters to 'C()' or to 'no_way_dude()'

>
> >> You can't since b and c are unrelated objects. The only relation
> >> is that both are members of A. So, the only way to reach one from
> >> the other is through an instance of A: a.b or a.c.

>
> >> Both B and C objects can exist as stand-alone objects:

>
> >> A::B A::GetB() const { return B(); }

>
> >> So there can not be a way to reach one from the other.

>
> > void A::C::no_way_dude()
> > {
> > * * A *a = 0;
> > * * B &b = *(B*)(((char*) this) - (char*) &a->c - (char*) &a->b);
> > * * // DONE!!!
> > }

>
> And what happens when you or someone else tries the following weeks,
> months or years later:
>
> int main()
> {
> * * A:C c;
>
> * * c.no_way_dude();
>
> * * return 0;
>
> }


You can make C constructor protected and A become C's friend.

> You basically have a (very) bad design.


It could be convenient in some cases if the standard provided more
tools to make it work.

--
Michael
 
Reply With Quote
 
Jeff Flinn
Guest
Posts: n/a
 
      12-22-2009
Michael Doubez wrote:
> On 22 déc, 16:01, Jeff Flinn <(E-Mail Removed)> wrote:
>> Chameleon wrote:
>>> στις 22 Δεκ 2009 15:32, O/H Gert-Jan de Vos *γραψε:
>>>> On Dec 22, 1:51 pm, Chameleon<(E-Mail Removed)> wrote:
>>>>> We have this structure:
>>>>> -----------------------
>>>>> struct A {
>>>>> struct B {
>>>>> ...
>>>>> } b;
>>>>> ...
>>>>> struct C {
>>>>> void no_way_dude();
>>>>> } c;};
>>>>> -----------------------
>>>>> How can I have access on 'b' from inside of 'no_way_dude()'?
>>>>> I mean without pass parameters to 'C()' or to 'no_way_dude()'
>>>> You can't since b and c are unrelated objects. The only relation
>>>> is that both are members of A. So, the only way to reach one from
>>>> the other is through an instance of A: a.b or a.c.
>>>> Both B and C objects can exist as stand-alone objects:
>>>> A::B A::GetB() const { return B(); }
>>>> So there can not be a way to reach one from the other.
>>> void A::C::no_way_dude()
>>> {
>>> A *a = 0;
>>> B &b = *(B*)(((char*) this) - (char*) &a->c - (char*) &a->b);
>>> // DONE!!!
>>> }

>> And what happens when you or someone else tries the following weeks,
>> months or years later:
>>
>> int main()
>> {
>> A:C c;
>>
>> c.no_way_dude();
>>
>> return 0;
>>
>> }

>
> You can make C constructor protected and A become C's friend.


Or just fix the design.

>> You basically have a (very) bad design.

>
> It could be convenient in some cases if the standard provided more
> tools to make it work.


In this case convenience makes for brittle code.

Jeff
 
Reply With Quote
 
Chameleon
Guest
Posts: n/a
 
      12-22-2009
στις 22 Δεκ 2009 17:11, O/H Vladimir Jovic *γραψε:
> Chameleon wrote:
>
> [snip]
>> void A::C::no_way_dude()
>> {
>> A *a = 0;
>> B &b = *(B*)(((char*) this) - (char*) &a->c - (char*) &a->b);
>> // DONE!!!
>> }

>
> Take a look at this:
> http://www.google.de/#hl=en&source=h...c34adcbfaca52f
>
>
>
> Why don't you move the no_way_dude() method from C to A? Then instead of
> passing objects of type C, pass objects of type A



Yes, this is what I wrote before.

But because A had many many members, I thought to group similar
functions of A in subclasses.

I realize that I am a little bit influenced from Java.
In Java if a subclass is not static can have access to parent class.
 
Reply With Quote
 
Michael DOUBEZ
Guest
Posts: n/a
 
      12-22-2009
Le 22/12/2009 18:04, Jeff Flinn a écrit :
> Michael Doubez wrote:
>> On 22 déc, 16:01, Jeff Flinn <(E-Mail Removed)> wrote:
>>> Chameleon wrote:
>>>> στις 22 Δεκ 2009 15:32, O/H Gert-Jan de Vos *γραψε:
>>>>> On Dec 22, 1:51 pm, Chameleon<(E-Mail Removed)> wrote:
>>>>>> We have this structure:
>>>>>> -----------------------
>>>>>> struct A {
>>>>>> struct B {
>>>>>> ...
>>>>>> } b;
>>>>>> ...
>>>>>> struct C {
>>>>>> void no_way_dude();
>>>>>> } c;};
>>>>>> -----------------------
>>>>>> How can I have access on 'b' from inside of 'no_way_dude()'?
>>>>>> I mean without pass parameters to 'C()' or to 'no_way_dude()'
>>>>> You can't since b and c are unrelated objects. The only relation
>>>>> is that both are members of A. So, the only way to reach one from
>>>>> the other is through an instance of A: a.b or a.c.
>>>>> Both B and C objects can exist as stand-alone objects:
>>>>> A::B A::GetB() const { return B(); }
>>>>> So there can not be a way to reach one from the other.
>>>> void A::C::no_way_dude()
>>>> {
>>>> A *a = 0;
>>>> B &b = *(B*)(((char*) this) - (char*) &a->c - (char*) &a->b);
>>>> // DONE!!!
>>>> }
>>> And what happens when you or someone else tries the following weeks,
>>> months or years later:
>>>
>>> int main()
>>> {
>>> A:C c;
>>>
>>> c.no_way_dude();
>>>
>>> return 0;
>>>
>>> }

>>
>> You can make C constructor protected and A become C's friend.

>
> Or just fix the design.


Since I don't know the problem space of the OP, I could not say anything
about the design. What he is trying to do is a pattern I know under the
name of 'memberspace':
http://accu.org/index.php/journals/1527

And if it fits his needs, he can simply put a comment in the code such as:
\warning this class is intended to be used in class A and nowhere else.

Because, of course, one reads the doc in the header before using a class

>>> You basically have a (very) bad design.

>>
>> It could be convenient in some cases if the standard provided more
>> tools to make it work.

>
> In this case convenience makes for brittle code.


It is certainly not something I would do on a daily basis but I don't
see where the robustness is impacted. In a well designed code, the
no_way_dude() would be the only responsibility of class C and there
would be no incentive to reuse it outside A.

--
Michael
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pointers, pointers, pointers... cerr C Programming 12 04-07-2011 11:17 PM
class members vs instance members hdixon Python 3 07-09-2006 06:56 PM
Difference between static final members and final static members(if any)? JFCM Java 4 02-07-2006 11:32 AM
Templates: Members Vs. non-members Dave C++ 3 08-10-2004 11:23 AM
Can nested class members access private members of nesting class? CoolPint C++ 8 12-14-2003 02:30 PM



Advertisments