开发者

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)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜