0

请验证我对指向成员的指针的理解是否正确。这是一个示例类:

class T
{
public:
       int *p;
       int arr[10];
};

对于“标准”指针,以下选项很常见:

int a = 1;
int *p1 = &a;
int *p2 = p1 (other notation: int *p2 = &*p1);
//The pointer p2 points to the same memory location as p1.

上述对成员指针的操作是不可能的:

int T::*pM = &(*T::p); // error

指向成员的指针包含内存中的偏移量,即从类的开始开始特定成员放置多远的信息,因此在这个阶段我们不知道类内的指针指向的位置。类似地,指向作为数组元素的成员的指针是不可能的,因为数组元素的地址是未知的:

int T::*pM = &T::arr[5]; //error

但以下操作是正确的:

int* T::*pM = &T::p; //a pointer to a pointer 
//the same operation for "standard" pointers:
int **p3 = &p2;
int (T::*pM)[10] = &T::arr; //a pointer to an array
4

1 回答 1

1

首先,首先使用解引用 + 运算符的地址并没有什么意义,并且在某些情况下会导致未定义的行为(例如,如果指针为空)。所以答案的前半部分是你一开始就不应该

答案的第二部分是指向成员的指针不是指针,而是访问给定对象的成员的机制。即使它们在名称中共享指针词,它们也是完全不同的野兽,您不能取消引用指向成员的指针,不能创建副本,不能出于任何其他原因或在任何其他上下文中。

关于指向存储在对象内部的数组成员的指针,问题在于该数组成员不是您的类型的成员,而是数组的成员。问题不在于位置未知,编译器非常清楚哪个是数组相对于完整对象的偏移量,哪个是数组元素在数组中的偏移量,并且编译器确实知道如何添加.

从最后三个例子来看,前两个很容易解释。给定一个类型T(无论是什么)和t该类型的一个对象,您可以T*通过获取对象的地址来创建 a: &t。是否T是类、指针、指向成员的指针、枚举......根本不重要。

最后,最后一种情况也很简单。给定一个类 C 和该类中类型为 T 的成员 m,您始终可以创建一个指向成员的指针,该指针m使用以下语法进行引用:T C::*ptr = &C::m;. 现在,类型的语法在 C 和 C++ 中很复杂,当类型T是数组时,类型会溢出到双方X (C::*ptr)[5],但这与更简单的阅读没有什么不同:

typedef int int5[5];
int5 T::*pM = &T::arr;
于 2013-11-06T17:27:53.907 回答