Is it possible to access a composite class data member with pointers to members ? The following code is not valid but demonstrate the need.
For example:
class A
{
public:
float fA;
};
class B
{
public:
float fB;
A a;
};
void test()
{
// Use of member pointer to access B::fB member
float B::*ptr = &B::fB; // -> OK
B myB;
myB.*ptr = 25.;
// Use of member pointer to access B::a.fA member ???
float B::*ptr2 = &B::a.fA; // -> ERROR
B myB.*ptr2 = 25.;
}
I've complete my question here : Pointer to composite class data member - Part 2
The obvious "reason" here is because fA
is not a member of
B
. In this particular case, implementing it would probably
not cause any particular problems, both orthogonality rules, and
for member functions, I don't think it could be implemented.
What you can do, of course, is take the address of the A
member of B
, then get to fA
through it:
A B::*ptr = &B::a;
(myB.*ptr).fa = 25.;
, for example. (I'm not sure that the parentheses are needed.
It's not a constrution that I use often enough to have the
precedences in my head.)
I agree with commenters, that probably you should ask how to do what you want, not how to do what you think will do what you want :)
As for the question: no, you cannot access B::a.fA
in this way. However, you can do the following:
A myA;
float A::*ptr2 = &A::fA; // -> OK now
myB.a.*ptr2 = 25.;
Or the following:
A B::*ptr3 = &B::a;
(myB.*ptr3).fA = 1.0f; // -> OK too
That is some weird looking syntax but if I understand you correctly, you are trying to access fA through class B. If that is the case, then you will need to create an instance of class B before class A is available to be accessed. Basically, if B doesn't exist, you can't access what is inside of it. The error is just what it sounds like, "left of .fA must have a class/struct/union" meaning your compiler can't figure out what is to the left of fA so the "a" is undefined or doesn't exist. Also, you have a redefinition error in there with B myB :)
No you cannot because the C++ syntax does not allow it. I don't see anything really special about what you're trying to do, but it's simply not considered in the language.
Note however that a pointer to data member is an object that given an instance will return a reference to a specific data member. You can implement this functionality manually relaxing the limitations:
struct A
{
double x;
double y;
static double& x_of(void *p) { return ((A *)p)->x; }
static double& y_of(void *p) { return ((A *)p)->y; }
};
struct B
{
double z;
A a;
static double& x_of(void *p) { return ((B *)p)->a.x; }
static double& y_of(void *p) { return ((B *)p)->a.y; }
static double& z_of(void *p) { return ((B *)p)->z; }
};
The type of the pointer is just double& (*)(void *)
and you can use this kind of trick even for example to return as member an element of an array.