about pointers on class' members

C

Chameleon

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?
 
G

Gert-Jan de Vos

We have this structure:
-----------------------
struct A {
        struct B {
        ...
        } b;

        ...

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

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.
 
C

Chameleon

στις 22 Δεκ 2009 15:32, O/H Gert-Jan de Vos έγÏαψε:
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!!!
}
 
M

Michael Doubez

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.
 
J

Jeff Flinn

Chameleon said:
στις 22 Δεκ 2009 15:32, O/H Gert-Jan de Vos έγÏαψε:

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
 
M

Michael Doubez

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.
 
J

Jeff Flinn

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

Or just fix the 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
 
C

Chameleon

στις 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=...ereferencing+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


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.
 
M

Michael DOUBEZ

Le 22/12/2009 18:04, Jeff Flinn a écrit :
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 :)
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top