Я понимаю, что с любой другой переменной тип параметра определяет взаимодействие между параметром и его аргументом. Мой вопрос заключается в том, что объясняет, почему вы ссылаетесь на параметр и почему вы этого не сделали? Почему некоторые параметры параметров ссылки, а некоторые нет? Не могли ли вы понять преимущества этого, может кто-нибудь объяснить?C++: Аргумент «Передано по ссылке»
ответ
Возможность пройти по ссылке, существует по двум причинам:
- Для того, чтобы изменить значение аргументов функции
- Чтобы избежать делать копии объекта по соображениям производительности
Пример для изменение аргумента
void get5and6(int *f, int *s) // using pointers
{
*f = 5;
*s = 6;
}
это может использоваться как :
int f = 0, s = 0;
get5and6(&f,&s); // f & s will now be 5 & 6
ИЛИ
void get5and6(int &f, int &s) // using references
{
f = 5;
s = 6;
}
это может быть использовано как:
int f = 0, s = 0;
get5and6(f,s); // f & s will now be 5 & 6
При переходе по ссылке, мы передать адрес переменной. Передача по ссылке аналогична передаче указателя - только адрес передается в обоих случаях.
Для например:
void SaveGame(GameState& gameState)
{
gameState.update();
gameState.saveToFile("save.sav");
}
GameState gs;
SaveGame(gs)
ИЛИ
void SaveGame(GameState* gameState)
{
gameState->update();
gameState->saveToFile("save.sav");
}
GameState gs;
SaveGame(&gs);
Поскольку только адрес передается значение переменной (которая может быть действительно огромный для больших объектов) Безразлично» t необходимо скопировать. Таким образом, передача по ссылке улучшает производительность, особенно когда:
- Объект, передаваемые функции огромен (я использовал бы вариант указателя здесь, так что абонент знает, что функция может изменить значение переменного)
- функцию можно было бы назвать много раз (например.в петле)
Также, читайте на const
ссылки. Когда он используется, аргумент не может быть изменен в функции.
Плюсы использования pass by reference: Вам не нужно создавать копию данных, которые вы передаете только указателю на нее в памяти. (огромный выигрыш в производительности, если у вас был массивный объект, который вы проходили). Вы можете «вернуть» несколько значений. Я знаю, что некоторые функции в c/C++ возвращают число, а один из параметров - указатель на данные, которые обрабатываются get.
Просьба использовать проход по ссылке: Вы должны быть осторожны, изменяя переданные данные, поскольку это может вызвать побочные эффекты, которые вы можете или не захотите.
Посредством ссылки в равной степени вручную передать переменную указателем, но по ссылке не позволит пользователю обрабатывать указатель «легко испортить».
Пожалуйста, забудьте про указатели на данный момент. И возьмите это с солью.
Ссылка объект. Когда вы проходите по ссылке, вы передаете объект.
При передаче по значению передается копия объекта; другой объект. Он может иметь то же самое состояние, но это другой экземпляр; клон.
Таким образом, это может иметь смысл, чтобы пройти по ссылке, если вы:
- необходимо изменить объект внутри функции
- не нужно (или хотят), чтобы изменить на объект, но хотелось бы избежать копирования только для передачи функции. Это будет ссылка
const
.
И это может иметь смысл передавать по значению, если вы:
- хотите начать с идентичноготвин и оставить оригинальный близнеца ненарушенных
- не волнует о стоимости копирования объекта (например, я не передал бы
int
по ссылке , если только Я не хотел его изменять).
Вот, посмотрите на этот код:
#include<iostream>
struct Foo {
Foo() { }
void describe() const {
std::cout<<"Foo at address "<<this<<std::endl;
}
};
void byvalue(Foo foo) {
std::cout<<"called byvalue"<<std::endl;
foo.describe();
}
void byreference(Foo& foo) {
std::cout<<"called byreference"<<std::endl;
foo.describe();
}
int main() {
Foo foo;
std::cout<<"Original Foo"<<std::endl;
foo.describe();
byreference(foo);
byvalue(foo);
}
И скомпилировать его так: g++ example.cpp
Выполнить это: ./a.out
И проверьте вывод (фактические адреса могут будет отличаться на вашем компьютере, но точка останется):
Original Foo
Foo at address 0x7fff65f77a0f
called byreference
Foo at address 0x7fff65f77a0f
called byvalue
Foo at address 0x7fff65f779f0
Обратите внимание, что адрес called byreference
совпадает с адресом Original Foo
(оба являются 0x7fff65f77a0f
). И обратите внимание, как called byvalue
адрес другой (это 0x7fff65f779f0
).
Поднять его на ступеньку.Измените код, чтобы выглядеть следующим образом:
#include<iostream>
#include<unistd.h> // for sleeping
struct Foo {
Foo() { }
Foo(const Foo&) {
sleep(10); // assume that building from a copy takes TEN seconds!
}
void describe() const {
std::cout<<"Foo at address "<<this<<std::endl;
}
};
void byvalue(Foo foo) {
std::cout<<"called byvalue"<<std::endl;
foo.describe();
}
void byreference(Foo& foo) {
std::cout<<"called byreference"<<std::endl;
foo.describe();
}
int main() {
Foo foo;
std::cout<<"Original Foo"<<std::endl;
foo.describe();
byreference(foo);
byvalue(foo);
}
скомпилировать его таким же образом, и обратите внимание на вывод (комментарии не в выходных данных, включенных для ясности):
Original Foo
Foo at address 0x7fff64d64a0e
called byreference
Foo at address 0x7fff64d64a0e # this point is reached "immediately"
called byvalue # this point is reached TEN SECONDS later
Foo at address 0x7fff64d64a0f
Таким образом, код предназначен преувеличивать стоимость копии: когда вы позвонили по ссылке, эта стоимость НЕ была произведена. Когда вы звонили по стоимости, вам пришлось ждать десять секунд.
Примечание: мой код был скомпилирован в OS X 10.7.4 с использованием GCC 4.8.1. Если вы находитесь в окнах, вам может понадобиться что-то отличное от unitsd.h
, чтобы сделать работу вызова sleep
.
Возможно, это помогает.
Спасибо, я был так смущен, когда «проходил по ссылке», называемый частным копиром ... – Kyslik
- 1. Q о [42000] и передано по ссылке
- 2. NSArray/NSMutableArray: передано по ссылке или по значению?
- 3. C++ float передано как аргумент неправильно напечатан
- 4. Юлия аргумент функции по ссылке
- 5. Аргумент функции Javascript по ссылке
- 6. Избегайте возвращения по ссылке аргумент
- 7. Предупреждение: передано по ссылке до того, как ему присвоено значение
- 8. C++ - Дополнительные аргументы по ссылке
- 9. Unset передано по ссылке, также не установлено исходное значение
- 10. В функциях julia: передано по ссылке или значению?
- 11. член переменный полиморфизм и аргумент по ссылке
- 12. C# параметры передачи по ссылке
- 13. Почему закрытие `take_while` принимает аргумент по ссылке?
- 14. Python: Передавать по ссылке модифицирует этот аргумент
- 15. Бросок временный аргумент, передаваемый по ссылке
- 16. Дополнительный аргумент, по ссылке, для полиморфного метода?
- 17. Objective-C ARC: как преобразовать (void *) ДА передано как аргумент?
- 18. Cython & C++: переход по ссылке
- 19. по ссылке в C++
- 20. C# назначить по ссылке
- 21. Объекты C# по ссылке
- 22. C++ Возвращаем по ссылке
- 23. C++ Вызов по ссылке
- 24. C++, проходящий по ссылке
- 25. Передайте аргумент по ссылке в C++/CLI, поэтому повторное присвоение влияет на вызывающего абонента
- 26. Передача значения по ссылке на C++
- 27. Передача массива по ссылке в C++
- 28. Передача указателя указателя по ссылке под C?
- 29. Если аргумент передается по ссылке в этом примере .net?
- 30. C++ передайте указатель по ссылке и присвойте значение по умолчанию
Создать вектор, содержащий 2gB данных. Теперь передайте его функции ... миллион раз. Я рекомендую этот вопрос. Обычно он начинается с «Не являются ли ссылки и указатели одинаковыми?» – WhozCraig
, так полезно ли всегда всегда ссылаться на параметры? или это не очень умная вещь? – Tyler
Нет Иногда существует определенная цель для передачи по значению. Это очень ситуационная ситуация. Некоторые из этих ситуаций могут быть чрезвычайно утонченными. – WhozCraig