В C++, что является различием между:
void func(MyType&); // declaration
//...
MyType * ptr;
func(*ptr); // compiler doesnt give error
func(ptr); // compiler gives error i thought & represents memory address so
// this statement should correct as ptr is only a pointer
// or address of some real var.
Оператор унарного префикса &
при применении к объекту дает адрес объекта: & obj
].
Модификатор типа &
, когда он применяется к переменной, которая будет объявлена, изменит тип переменной на ссылочный тип : int &
.
То же самое применимо к *
: при применении к указателю в качестве унарного префиксного оператора он разыменует указатель, в результате чего будет получен объект, на который делается ссылка: * ptr
.
При использовании в качестве модификатора типа для переменной, которая будет объявлена, *
изменит тип на указатель : int *
.
Аналогичным образом модификатор типа []
, примененный к объявляемой переменной, изменит тип переменной на массив, в то время как бинарный инфиксный оператор []
применяется к объекту массива type будет обращаться к одному из подобъектов массива.
Бесполезно, что модификаторы типа применяются к объявленной переменной , а не к типу, с которым они объявлены. Например, этот
int *p, **pp, i, a[10], &r = i;
определяет указатель int
, указатель на указатель на int
, ванильный int
, массив из 10 int
и ссылка int
. (Последний сразу инициализируется, потому что у вас не может быть неинициализированной ссылки.) Обратите внимание, что модификаторы типа синтаксически принадлежат объявленной переменной , тип которой они изменяют, а не типу объявленной переменной.Тем не менее, модификаторы типа ( *
и &
) изменяют тип переменной.
Однако в следующем случае, когда p
, i
и a
предположительно являются переменными, которые уже были объявлены
*pp = &i;
a[0] = i;
*
и &
- унарные префиксные операторы разыменования pp
и возвращающие адрес i
, тогда как []
возвращает первый объект int
в массиве а
.
Тот факт, что C и C ++ не заботятся о пробелах вокруг модификаторов типов , и что это привело к различным лагерям, когда дело доходит до их размещения, на самом деле ничего не значит Полегче.
Некоторые люди помещают модификаторы типа близко к типу. Они утверждают, что он изменяет тип и поэтому должен быть там:
int* ptr;
Недостатком является то, что это сбивает с толку при объявлении нескольких объектов. Этот
int* a, b;
определяет a
как указатель на int
, но b
как int
. Вот почему некоторые люди предпочитают писать
int *ptr;
int *a, *b;
. Я предлагаю просто никогда не объявлять несколько объектов в одном операторе. IMO, который упрощает чтение кода. Кроме того, вы можете выбрать любое соглашение.
Чтобы еще больше усложнить ситуацию, помимо модификаторов типа и унарных префиксных операторов &
и *
, существуют также бинарные инфиксные операторы &
и *
, означающие «поразрядное И» и «умножение».И чтобы добавить оскорбления к травмам, в C ++ вы можете перегрузить как унарный префикс , так и варианты двоичного инфикса этих операторов (а также двоичный инфиксный ] []
) для определяемых пользователем типов и быть полностью свободными в отношении их семантики.
MyType & представляет собой / ссылку /, совершенно другого зверя по сравнению с указателями. Если прототип вашей функции был
func (MyType);
вы будете работать с копией аргумента внутри функции. С помощью
func (MyType &);
вы работаете с самим объектом (т.е., тот же объект как в вызывающей, так и в вызываемой области). В данном случае это похоже на работу с указателем, но с использованием того же синтаксиса «точки», что и для объектов.
Конечно, это поверхностное и упрощенное объяснение. На то, чтобы разобраться в глубинах указателей, ссылок и прочей орды, мне потребовались годы.