Передать указатель & Pass по ссылке
Возможный дубликат:
Каковы различия между переменной указателя и ссылочной переменной в С++?
Есть ли преимущества передачи указателем на передачу по ссылке в С++?
В обоих случаях я достиг результата.
Итак, когда один предпочтительнее другого? Каковы причины, по которым мы используем один над другим?
#include <iostream>
using namespace std;
void swap(int* x, int* y)
{
int z = *x;
*x=*y;
*y=z;
}
void swap(int& x, int& y)
{
int z = x;
x=y;
y=z;
}
int main()
{
int a = 45;
int b = 35;
cout<<"Before Swap\n";
cout<<"a="<<a<<" b="<<b<<"\n";
swap(&a,&b);
cout<<"After Swap with pass by pointer\n";
cout<<"a="<<a<<" b="<<b<<"\n";
swap(a,b);
cout<<"After Swap with pass by reference\n";
cout<<"a="<<a<<" b="<<b<<"\n";
}
Выход
Before Swap
a=45 b=35
After Swap with pass by pointer
a=35 b=45
After Swap with pass by reference
a=45 b=35
Ответы
Ответ 1
Ссылка семантически:
T& <=> *(T * const)
const T& <=> *(T const * const)
T&& <=> [no C equivalent]
(С++ 11)
Как и в случае с другими ответами, из С++ часто задается однострочный ответ: ссылки, когда это возможно, указатели при необходимости.
Преимущество над указателями заключается в том, что для передачи NULL требуется явное литье.
Это все еще возможно.
Из компиляторов, которые я тестировал, ни один из них не выдает предупреждение для следующего:
int* p() {
return 0;
}
void x(int& y) {
y = 1;
}
int main() {
x(*p());
}
Ответ 2
Фактически, большинство компиляторов выделяют один и тот же код для обоих вызовов функций, поскольку ссылки обычно реализуются с помощью указателей.
Следуя этой логике, когда аргумент (неконстантного) ссылочного типа используется в теле функции, сгенерированный код будет просто действовать по адресу аргумента, и он будет разыменовывать его. Кроме того, при вызове такой функции компилятор будет генерировать код, который передает адрес аргументов вместо копирования их значения.
В основном ссылки и указатели не отличаются друг от друга с точки зрения реализации Основная (и очень важная) разница в философии: ссылка - это сам объект, просто с другим именем.
Ссылки имеют еще несколько преимуществ по сравнению с указателями (например, они не могут быть NULL
, поэтому они более безопасны в использовании). Следовательно, если вы можете использовать С++, то переход по ссылке обычно считается более элегантным, и это должно быть предпочтительным. Однако в C нет передачи по ссылке, поэтому, если вы хотите написать C-код (или, horribile dictu, код, который компилируется как с C, так и с С++-компилятором, хотя это и не очень хорошая идея), вам придется ограничьте себя использованием указателей.
Ответ 3
Передача по указателю - это единственный способ передать "по ссылке" в C, поэтому вы все равно видите, что он используется довольно немного.
Указатель NULL - удобное соглашение о том, что параметр не используется или недействителен, поэтому используйте в этом случае указатель.
Ссылки не могут быть обновлены после их установки, поэтому используйте указатель, если вам нужно переназначить его.
Предпочитайте ссылку в каждом случае, где нет веской причины. Сделайте это const
, если сможете.
Ответ 4
Здесь - хорошая статья по этому вопросу - "Используйте ссылки, когда сможете, и указатели, когда вам нужно".
Ответ 5
Используйте ссылки все время и указатели только тогда, когда вам нужно обратиться к NULL
, ссылка на которую не может ссылаться.
Смотрите этот FAQ:
http://www.parashift.com/c++-faq-lite/references.html#faq-8.6