2013-11-06 3 views
0

Проверьте, верно ли мое понимание указателя на элемент. Ниже приведен пример класса:Указатель на элемент: указатель и элемент массива

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

Для "стандартных" указателей следующих opartions являются общими:

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 

Указатель член содержит смещение в памяти, то есть информацию о том, как далеко находится конкретный участник, начинающийся с начала класса, поэтому мы не знаем об этом этот этап , где указатель внутри точек класса. Similary указатель на элемент, который является элементом массива невозможно, так как адрес элемента массива неизвестен:

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 
+0

Я предлагаю что вы задаете один вопрос одновременно. Дополнительную информацию о запросе см. В [help] (http://stackoverflow.com/help/asking). –

+1

Так в чем же вопрос, в конце концов? –

+1

Несмотря на имя, указатель на элемент является * не * указателем и не ведет себя так. Не имеет смысла говорить о «той же операции» для обоих типов, так как нет никаких операций, применимых к обоим. Ваши ошибки связаны с попыткой разыменовать его (вы можете только указатели разыменования) и пытаться указать что-то другое, кроме члена (так как только массив является членом, а не его элементами). –

ответ

1

Первое состоит в том, что она не действительно имеет смысл использовать разнесение + адрес оператора в первую очередь, и это может вызвать неопределенное поведение в случаях (например, если указатель имеет значение null). Так что в первой половине ответа вы не должны в первую очередь.

Вторая часть ответа заключается в том, что указатель-член является не указателем, а механизмом доступа к члену, данному объекту. Даже если они разделяют слово в своих именах, они совершенно разные звери, и вы не можете разыменовывать указатель на член, а не создавать копию, а не по какой-либо другой причине или в любом другом контексте.

Что касается указателя на элемент массива, который хранится внутри вашего объекта, проблема в том, что этот элемент массива равен , а не - член вашего типа, но является членом массива. Проблема заключается не в том, что местоположение неизвестно, это очень хорошо известно компилятору, который является смещением массива от полного объекта и который является смещением элемента массива в массиве, а компилятор знает, как добавить ,

Из последних трех примеров первые два просто прояснить. Если задан тип T (что бы это ни было) и объект t этого типа, вы можете создать T*, взяв адрес объекта: &t. Является ли T классом, указателем, указателем на член, перечислением ... не имеет значения вообще.

Наконец, последний случай снова прост. Учитывая класс C и член m типа T в этом классе, вы всегда можете создать указатель-член, который ссылается на m, используя синтаксис: T C::*ptr = &C::m;. Теперь грамматика типов осложняется в C и C++ и когда тип T представляет собой массив типа проливает к обеим сторонам, как в X (C::*ptr)[5], но это ничем не отличается, чем проще читать:

typedef int int5[5]; 
int5 T::*pM = &T::arr; 
Смежные вопросы