Reputation: 75
I'm staring at the following code snippet, trying to understand what's going on, or at least how to name what i'm seeing to google it up.
struct A {
A *m_ptr;
typedef A * (A::*T);
operator T() const {
return &A::m_ptr;
}
};
I figured out that operator T()
is an overloaded conversion operator to type T
, while type T
is a typedef to represent A*(A::*)
. Now,
A::*
?A*
?A::
in the return
statement make?Upvotes: 0
Views: 41
Reputation: 206607
what exactly is
A::*
?
It's a pointer to a member of A
. Type type A* (A::*)
is a pointer to a member of A
of type A*
.
what's the difference between that and
A*
?
It's a pointer to an object of type A
.
and what sense does the
A::
in the return statement make?
&(A::m_ptr)
is a pointer to the m_ptr
member of an object.
An example program that explores the idea a little bit more:
#include <iostream>
struct A {
A *m_ptr1;
A *m_ptr2;
typedef A * (A::*T);
operator T() const {
return &A::m_ptr1;
}
A(int d) : data(d) {}
int data;
};
int main()
{
A::T ap1 = &A::m_ptr1;
A::T ap2 = &A::m_ptr2;
A a1(10);
A a2(20);
a1.*ap1 = &a1; // a1.m_ptr1 points to a1.
a1.*ap2 = &a2; // a1.m_ptr2 points to a2.
a2.*ap1 = &a2; // a2.m_ptr1 points to a2.
a2.*ap2 = &a1; // a2.m_ptr2 points to a1.
std::cout << "a1.data: " << a1.data << std::endl;
std::cout << "a1.m_ptr1->data: " << a1.m_ptr1->data << std::endl;
std::cout << "a1.m_ptr2->data: " << a1.m_ptr2->data << std::endl;
std::cout << "a2.data: " << a2.data << std::endl;
std::cout << "a2.m_ptr1->data: " << a2.m_ptr1->data << std::endl;
std::cout << "a2.m_ptr2->data: " << a2.m_ptr2->data << std::endl;
}
Output:
a1.data: 10
a1.m_ptr1->data: 10
a1.m_ptr2->data: 20
a2.data: 20
a2.m_ptr1->data: 20
a2.m_ptr2->data: 10
Upvotes: 3
Reputation: 171303
what's the difference between that and
A*
?
X*
is the address of an X
object, whereas X Y::*
is a pointer-to-member that points to a member of class Y
of type X
.
The difference is that a pointer is the address of an object.
A pointer-to-member is more like an offset, because it's not an actual address, it is relative to some object. It tells you how to get a member given some object. You can't dereference a pointer-to-member on its own, you have to combine it with an object to dereference it.
You create a pointer-to-member by using the &
operator on a qualified-id, so &x
means "take the address of the object x
" but &Y::x
means get a pointer-to-member for the member x
of class Y
.
You dereference a pointer-to-member by combining it with an object (or pointer to object) using the .*
operator (or ->*
operator).
e.g.
struct Y { int i; int j; };
int Y::* memptr = &Y::i;
Y y;
int& i = y.*memptr;
memptr = &Y::j;
int& j = y.*memptr;
Upvotes: 1