0

I just saw a post in which I found something I never saw before, in short here it is:

class A {
public:
    int _x;
};

void foo(A *a_ptr, int *m_ptr)
{
    cout << (*a_ptr).*m_ptr << endl;  // here
}

int main()
{
    A a;
    a._x = 10;
    foo(&a, &A::_x);   // and here
}

How could it be done? Pass in &A::_x, and later refer it using (*a_ptr).*m_ptr?

I thought, &A::_x will always refer to the same address, but different objects have different _x, how could it be done?

Community
  • 1
  • 1
Alcott
  • 17,905
  • 32
  • 116
  • 173

1 Answers1

3

&A::_x is a pointer-to-member, which is not a pointer. Rather, think of it as some relative sort of construct which tells you where inside an object you find a particular member element. Only together with an instance reference can you locate the actual subobject of that instance which is given by the member pointer.

Compare:

struct Foo { int x; int y; };

Foo a = { 1, 2 };
Foo b = { 3, 4 };
Foo c = { 5, 6 };

int * p = &a.x;  // ordinary pointer-to-int

int Foo::*pm = &Foo::x;             // pointer-to-member
int result = a.*pm + b.*pm + c.*pm; // aggregate Foo::x
// point to a different member:
pm = &Foo::y;
result = a.*pm + b.*pm + c.*pm;     // aggregate Foo::y
Xeo
  • 129,499
  • 52
  • 291
  • 397
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084