Ссылка против указателя

в чем разница? Потому что это:

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;
  }
}