Что означает `* &` в объявлении функции?
Я написал функцию по строкам:
void myFunc(myStruct *&out) {
out = new myStruct;
out->field1 = 1;
out->field2 = 2;
}
Теперь в вызывающей функции я могу написать что-то вроде этого:
myStruct *data;
myFunc(data);
который заполнит все поля в data
. Если я опускаю '&
' в декларации, это не сработает. (Вернее, он будет работать только локально в функции, но ничего не изменит в вызывающем абоненте)
Может ли кто-нибудь объяснить мне, что на самом деле делает этот *&
? Это выглядит странно, и я просто не могу этого толковать.
Ответы
Ответ 1
Символ и символ в объявлении переменной С++ означает reference.
Это ссылка на указатель, который объясняет семантику, которую вы видите; вызываемая функция может изменить указатель в вызывающем контексте, поскольку он имеет ссылку на него.
Итак, чтобы повторить, "действующий символ" здесь не *&
, эта комбинация сама по себе не означает много. *
является частью типа myStruct *
, то есть "указатель на myStruct
", а &
делает его ссылкой, поэтому вы читаете его как "out
является ссылкой на указатель на myStruct
".
Оригинальный программист мог бы, на мой взгляд, помочь, написав его как:
void myFunc(myStruct * &out)
или даже (не мой личный стиль, но, конечно, все еще действителен):
void myFunc(myStruct* &out)
Конечно, есть много других мнений о стиле.:)
Ответ 2
В C и С++ и означает вызов по ссылке; вы позволяете функции изменять переменную.
В этом случае ваша переменная является указателем на тип myStruct. В этом случае функция выделяет новый блок памяти и присваивает это вашему указателю "данные".
В прошлом (скажем, K & R) это должно было быть сделано путем передачи указателя, в данном случае указателя на указатель или **. Оператор ссылки позволяет считывать более читаемый код и более надежную проверку типов.
Ответ 3
Похоже, вы перепроектируете конструктор!
Почему бы просто не создать соответствующий конструктор?
Обратите внимание, что в С++ структура похожа на класс (он может иметь конструктор).
struct myStruct
{
myStruct()
:field1(1)
,field2(2)
{}
};
myStruct* data1 = new myStruct;
// or Preferably use a smart pointer
std::auto_ptr<myStruct> data2(new myStruct);
// or a normal object
myStruct data3;
Ответ 4
Возможно, стоит объяснить, почему это не &*
, но наоборот. Причина в том, что объявления создаются рекурсивно, и поэтому ссылка на указатель строится, например,
& out // reference to ...
* (& out) // reference to pointer
Скобки закрываются, поскольку они избыточны, но они могут помочь вам увидеть шаблон. (Чтобы понять, почему они избыточны, представьте, как выглядит вещь в выражениях, и вы заметите, что сначала был взят адрес, а затем разыменован - тот порядок, который мы хотим, и что скобки не будут меняться). Если вы измените заказ, вы получите
* out // pointer to ...
& (* out) // pointer to reference
Указатель ссылки не является законным. Поэтому порядок *&
, что означает "ссылка на указатель".
Ответ 5
Как и другие, и означает, что вы ссылаетесь на действительную переменную в функцию, а не на ее копию. Это означает, что любые изменения, внесенные в переменную в функции, влияют на исходную переменную. Это может стать особенно запутанным, когда вы передаете указатель, который уже является ссылкой на что-то еще. В случае, если ваша подпись функции выглядела так:
void myFunc(myStruct *out);
Что произойдет, так это то, что вашей функции будет передана копия указателя для работы. Это означает, что указатель указывает на одно и то же, но будет другой переменной. Здесь любые изменения, сделанные в *out
(т.е. Какие точки в точке) были бы постоянными, но изменения, сделанные в out
(сам указатель), будут применяться только в myFunc
. С такой подписью
void myFunc(myStruct *&out);
Вы объявляете, что функция будет ссылаться на исходный указатель. Теперь любые изменения, внесенные в переменную-указатель out
, будут влиять на исходный указатель, который был передан.
При этом линия
out = new myStruct;
изменяет переменную указателя out
, а не *out
. Независимо от того, что out
используется для указания, все еще жив и здоров, но теперь новый кусок myStruct был создан в куче, а out
был изменен, чтобы указать на него.
Ответ 6
См. wikipedia
Ответ 7
В С++ это ссылка на указатель, эквивалентная указателю на указатель на C, поэтому аргумент функции присваивается.
Ответ 8
Как и в большинстве типов данных в С++, вы можете прочитать его справа налево, и это будет иметь смысл.
myStruct *&out
out
является ссылкой (&
) на указатель (*
) на объект myStruct
. Это должно быть ссылкой, потому что вы хотите изменить то, что указывает out
(в данном случае a new myStruct
).
Ответ 9
MyClass * & MyObject
Здесь MyObject является ссылкой на указатель MyClass. Поэтому вызов myFunction (MyClass * & MyObject) является вызовом по ссылке, мы можем изменить MyObject, который ссылается на указатель. Но если мы делаем myFunction (MyClass * MyObject), мы не можем изменить MyObject, потому что это вызов по значению, он просто скопирует адрес во временную переменную, чтобы мы могли изменить значение, где MyObject является Pointing, но не MyObject.
поэтому в этом случае писатель сначала назначает новое значение, из-за чего требуется вызов по ссылке.