Ссылка против указателя
в чем разница? Потому что это:
int Value = 50;
int *pValue = &Value;
*pValue = 88;
и версия ref делают то же самое:
int Value = 50;
int &rValue = Value;
rValue = 88;
какой из них лучше использовать? Спасибо.
6 ответов
в этом случае они эквивалентны.
не имеет значения, какой вы используете, и не является "лучшей".
Если вы действительно хотите, чтобы выбрать между ними, то ссылка наверное более идиоматические. Я обычно придерживаюсь ссылок везде, где могу, потому что моему ОКР это нравится: они чувствуют себя "более жесткими", не могут быть повторно связаны (с вами или без вас) и не требуют разыменования, чтобы добраться до значения.
но я не знаю ни одного общий консенсус по этому вопросу в таких случаях.
также обратите внимание, что эти два могут не компилироваться в один и тот же код, если ваша реализация не реализует ссылки с указателями, хотя я не знаю такой реализации, и вы все равно не заметите разницы.
указатель-это адрес ячейки памяти. Вы можете изменить значение этого адреса, чтобы указать на разные адреса памяти.
ссылка-это псевдоним переменной. Этот псевдоним можно назначить только во время объявления. Вы не можете изменить, какая переменная является псевдонимом ссылки после ее объявления.
следующие назначения указателей невозможны со ссылками.
int a = 10;
int b = 20;
int* pInt = NULL; // A pointer pointing at nothing.
pInt = &a; // pInt now points at a
pInt = &b; // pInt now points at b
а какой лучше, это все зависит от контекста.
я использую ссылки для параметров метода и функции.
void updateFoo(Foo& foo)
я использую ссылки на сложные объекты псевдонимов.
Foo& foo = bar.getBaz().getFoo(); // easy access to foo
я использую указатели на динамически выделенные объекты.
Foo* pFoo = new Foo();
я использую указатели для вещей, которые могут указывать на разные значения (включая отсутствие значения вообще).
Foo* pFoo = NULL;
if (condition1)
pFoo = &foo1;
else (condition2)
pFoo = &foo2;
как правило, я по умолчанию использую ссылки и указатели в местах, где ограничения на ссылки вызывают проблемы.
отличия:
ссылка является псевдонимом объекта и имеет тот же адрес, что и объект.
int a; // address of a : 0x0012AB
int &ref = a; // address of ref : 0x0012AB (the same)
ссылки должен быть инициализирован :
int &ref = a; // GOOD, is compiling
int &ref; // BAd, is not compiling
указатель-это еще одна переменная, которая содержит адрес:
int a = 5; // address of a : 0x0012AB
int *p = &a; // address of p : 0x0012AF (is different )
// value of a is 5
// value of p is 0x0012AB (address of a)
указатели могут быть NULL
int *p = NULL;
мое эмпирическое правило состоит в том, чтобы использовать ссылку или ссылку const, если указатель не требуется.
ссылка не может быть переустановлена, и она синтаксически чище. Ссылка также гарантирует вам, что ссылка не NULL
.
Я также могу использовать указатель для удобства при использовании массивов.
Я согласен с ответом Джастина и хотел бы уточнить его с самым крошечным примером.
Предположим, вы не совсем помните синтаксис геометрической библиотеки 2D-изображений: это
bool BooleanOr( const Bitmap & input1, const Bitmap & input2, Bitmap * output );
или
bool BooleanOr( Bitmap * output, const Bitmap & input1, const Bitmap & input2 );
Если в вашей компании все используют указатели для выходов и ссылки const для входов, практически невозможно ошибиться: когда вы видите такие вызовы, как
BooleanOr( thisBitmap, thatBitmap, & anotherBitmap );
вы сразу знаете синтаксис.
большие ответы здесь. Я хотел бы указать на 2 конкретных использования ссылок: -
Случай 1: при реализации operator[]
. Этот оператор обычно должен возвращать что-то это можно использовать как цель задания пример:
vector<int> v(20);
v[1] = 5; //The target of the assignment is the return value of operator []
на operator []
возвращает ссылка элемента с указанным индексом в vector
. Had operator []
был разработан, чтобы вернуть указатель к элементу по указанному индексу 2-я строка должна быть написана так: -
*v[1] = 5
, что составляет v
похоже, что это вектор указателей - что это определенно не так!! Таким образом, для торжества здравомыслия -operator []
возвращает ссылка, а не указатель к индексированному элементу в векторе
случай 2: нет явного null
проверьте наличие ссылок. Некоторые ответы уже говорили об этом - хотел представьте преимущество, используя фрагмент кода: -
void fun(const int& val)
{
cout << val;
}
void fun(const int* val)
{
if (val){ //Additional overhead with pointers
cout << *val;
}
}