a***n 发帖数: 538 | 1 完整的code
https://gist.github.com/3343011
#include
int main()
{
struct F {
int x;
} foo, *foo_ptr = &foo;
int F::*x = &F::x;
foo.*x = 42;
printf("%d\n", foo_ptr->*x);
}
怎么也看不明白第8行啊 | f******y 发帖数: 2971 | 2 指向member的一个指针。
【在 a***n 的大作中提到】 : 完整的code : https://gist.github.com/3343011 : #include : int main() : { : struct F { : int x; : } foo, *foo_ptr = &foo; : int F::*x = &F::x; : foo.*x = 42;
| y****e 发帖数: 23939 | 3 They use the same name 'x' for pointer and the class member variable name.
It looks like they intentionally trying to confuse reader.
I we write it as:
int F::*px = &F::x;
it would be much clearer.
【在 f******y 的大作中提到】 : 指向member的一个指针。
| a***n 发帖数: 538 | 4 但是这个指针存在什么地方了?sizeof(F)还是4啊。 | m*******l 发帖数: 12782 | 5 LOCAL STACK
【在 a***n 的大作中提到】 : 但是这个指针存在什么地方了?sizeof(F)还是4啊。
| a***n 发帖数: 538 | 6 #include
int main()
{
struct F {
int x;
} f1;
f1.x = 41;
int F::*px = &F::x;
F f2;
f2.x = 42;
printf("%d %d\n", f1.*px, f2.*px);
}
为什么f1.*px也是对的啊? | f******y 发帖数: 2971 | 7 变量名想用什么就用什么。
【在 a***n 的大作中提到】 : #include : int main() : { : struct F { : int x; : } f1; : f1.x = 41; : int F::*px = &F::x; : F f2; : f2.x = 42;
| a***n 发帖数: 538 | 8 原来如此啊。
实际上是定义了px的一个指针offset。.*和->*是指针offset呀。 | e*****w 发帖数: 144 | 9 I think this syntax is in C99 but not in C++. | f*******n 发帖数: 12623 | 10 No, this is C++. Not C.
【在 e*****w 的大作中提到】 : I think this syntax is in C99 but not in C++.
| j*****g 发帖数: 16 | 11 (From "Thinking in C++")
Pointers to members
A pointer is a variable that holds the address of some location. You can
change what a pointer selects at runtime, and the destination of the pointer
can be either data or a function. The C++ pointer-to-member follows this
same concept, except that what it selects is a location inside a class. The
dilemma here is that a pointer needs an address, but there is no “address”
inside a class; selecting a member of a class means offsetting into that
class. You can’t produce an actual address until you combine that offset
with the starting address of a particular object. The syntax of pointers to
members requires that you select an object at the same time you’re
dereferencing the pointer to member.
To understand this syntax, consider a simple structure, with a pointer sp
and an object so for this structure. You can select members with the syntax
shown:
//: C11:SimpleStructure.cpp
struct Simple { int a; };
int main() {
Simple so, *sp = &so;
sp->a;
so.a;
} ///:~
Now suppose you have an ordinary pointer to an integer, ip. To access what
ip is pointing to, you dereference the pointer with a ‘*’:
*ip = 4;
Finally, consider what happens if you have a pointer that happens to point
to something inside a class object, even if it does in fact represent an
offset into the object. To access what it’s pointing at, you must
dereference it with *. But it’s an offset into an object, so you must also
refer to that particular object. Thus, the * is combined with the object
dereference. So the new syntax becomes –>* for a pointer to an object, and
.* for the object or a reference, like this:
objectPointer->*pointerToMember = 47;
object.*pointerToMember = 47;
Now, what is the syntax for defining pointerToMember? Like any pointer, you
have to say what type it’s pointing at, and you use a * in the definition.
The only difference is that you must say what class of objects this pointer-
to-member is used with. Of course, this is accomplished with the name of the
class and the scope resolution operator. Thus,
int ObjectClass::*pointerToMember;
defines a pointer-to-member variable called pointerToMember that points to
any int inside ObjectClass. You can also initialize the pointer-to-member
when you define it (or at any other time):
int ObjectClass::*pointerToMember = &ObjectClass::a;
There is actually no “address” of ObjectClass::a because you’re just
referring to the class and not an object of that class. Thus,&ObjectClass::a
can be used only as pointer-to-member syntax.
Here’s an example that shows how to create and use pointers to data members:
//: C11:PointerToMemberData.cpp
#include
using namespace std;
class Data {
public:
int a, b, c;
void print() const {
cout << "a = " << a << ", b = " << b
<< ", c = " << c << endl;
}
};
int main() {
Data d, *dp = &d;
int Data::*pmInt = &Data::a;
dp->*pmInt = 47;
pmInt = &Data::b;
d.*pmInt = 48;
pmInt = &Data::c;
dp->*pmInt = 49;
dp->print();
} ///:~
Obviously, these are too awkward to use anywhere except for special cases (
which is exactly what they were intended for).
Also, pointers to members are quite limited: they can be assigned only to a
specific location inside a class. You could not, for example, increment or
compare them as you can with ordinary pointers. |
|