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?
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!!!
}
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
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
[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=hp&q=dereferencing+null+pointer&btnG=Google+Search&aq=f&oq=dereferencing+null+pointer&fp=4fc34adcbfaca52f
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
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
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
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.
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