简体   繁体   中英

pointer to member: pointer and array element

Please verify if my understanding about a pointer to member is correct. Here is an example class:

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

For "standard" pointers following opartions are common:

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.

The above operation for a pointer to member is impossible:

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

A pointer to member contains an offset in the memory ie information how far away is placed particular member starting from the beggining of the class, so we don't know at this stage where a pointer inside the class points. Similary a pointer to member which is an array element is impossible because the address of the array element is unknown:

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

But following operations are correct:

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

The first thing is that it does not really make sense to use dereference + address of operator in the first place, and it can cause undefined behavior in cases (for example, if the pointer is null). So the first half of the answer is you shouldn't in the first place.

The second part of the answer is that a pointer-to-member is not a pointer, but a mechanism to access a member given an object. Even if they share the pointer word in their names, they are completely different beasts and you cannot dereference a pointer-to-member, not to create a copy, not for any other reason or in any other context.

Regarding a pointer to a member of an array that is stored inside your object, the problem is that that array member is not a member of your type, but a member of the array. The problem is not that the location is unknown, it is very well known to the compiler which is the offset of the array from the complete object and which is the offset of the array element within the array, and the compiler does know how to add.

From the last three examples, the first two are just plain simple to explain. Given a type T (whatever that is) and an object t of that type, you can create a T* by taking the address of the object: &t . Whether T is a class, a pointer, a pointer-to-member, enum... does not matter at all.

Finally the last case is again simple. Given a class C and a member m of type T within that class, you can always create a pointer-to-member that refers to m by using the syntax: TC::*ptr = &C::m; . Now the grammar for types is complicated in C and C++ and when the type T is an array the type spills to both sides as in X (C::*ptr)[5] , but that is not different than the simpler to read:

typedef int int5[5];
int5 T::*pM = &T::arr;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM