Pointer to a pointer's attribute
Is there any way to simulate this situation in C++?
I have two objects A
and B
, each one has one attribute, for example, int i
;
Also I have one pointer po
pointing to an object and one pointer pi
pointing to an integer. I want to have the integer pointer pointing to the attribute in the current objec开发者_开发技巧t pointed by the pointer.
Something like:
po = A;
pi = po->i;
// pi points to A.i
po = B;
// now pi points to B.i
I'm almost sure this can't be achieved using pointers, but I want to know if there's any work around to do it.
What you're looking for is called 'pointers to members'. Suppose that A and B are of type T, then you can write:
struct T { int i; };
T A, B, C; // some objects of this type
int T::*pi = &T::i; // pi is a pointer to an int member of T
T* po;
po = &A;
cout << po->*pi << '\n'; // prints A.i
po = &B;
cout << po->*pi << '\n'; // prints B.i
cout << C.*pi << '\n'; // prints C.i
struct O
{
int i;
};
struct P
{
void operator=(O & rhs)
{
po = &rhs;
pi = &rhs.i;
}
O * po;
int * pi;
};
int main()
{
P po;
int *& pi = po.pi;
O A,B;
A.i = 7;
B.i = 19;
po = A;
cout << *pi << endl;
po = B;
cout << *pi << endl;
}
Actually you can't do that straight forward.
pi
would have to be notified/changed if po
changes. With pi
being an object of a new ty pe AutoReference
you could achieve it, but nobody will understand the code.
What I mean with "not straight forward" is: The following works but don't do it.
class AutoReference
{
public:
AutoReference( ClassA ** ppObj )
: mppObj( ppObj )
{
}
ClassA * operator->()
{
return *mppObj;
}
private:
ClassA ** mppObj;
};
po = A;
AutoReference pi( &po );
// pi "points" to A.i
po = B;
// now pi "points" to B.i
Or you could just do a pointer to the pointer, if that suits your situation better.
T a, b;
a.i = 6;
b.i = 9;
T* po = &a;
T** pi = &po;
std::cout << (*pi)->i; // Prints 6
po = &b;
std::cout << (*pi)->i; // Prints 9
In short, this cannot be done the way you have specified. Nor would you really want it to.
Just imagine the chaos that would rain down on your application if changing one variable also changed other completely distinct variables. It would be like dogs & cats living together. Mass hysteria.
But there's also little point to doing exactly what you've asked for, and this makes me think that what you're really after is something else entirely. For example, in your above example, it would be much simpler to just do this:
po = A;
int ai = po->i;
po = B;
int ab = po->i;
So, what are you really trying to do?
As you have written it:
pi continues to point to A.i when po points to B.
What's wrong with using
po = &A;
// do stuff using po and po->i (A and A.i)
po = &B;
// do stuff using po and po->i (B and B.i)
This would work, but I find this ugly.
class MyObject
{
public:
int m_i;
};
class AutomaticPointerToMember
{
public:
AutomaticPointerToMember(MyObject& obj,int MyObject::*):
m_Object(obj),
m_pInt(NULL)
{}
operator int* ()
{
return &(m_Object.*m_pInt);
}
int operator* ()
{
return (m_Object.*m_pInt);
}
private:
MyObject& m_Object;
int MyObject::* m_pInt;
};
void test()
{
MyObject a;
MyObject b;
MyObject * pObj = &a;
AutomaticPointerToMember pi(*pObj, &MyObject::m_i);
int * pIa = pi; // pIa points to a.i
int ia = *pi; // value a.i
pObj = &b; // pObj now points to b
int * pIb = pi; // pIb points to b.i
int ib = *pi; // value b.i
}
and one would have to define also operator &, *& and so on, so as to define a politically correct smart pointer...
struct S {
int i;
};
S a, b;
A * ap = & a;
int * ip = &(ap->i);
ip now points at a's i member (note these are not referred to as attributes in C++ land)
精彩评论