Ссылка на указатель

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

int Value = 50;
int *pValue = &Value;

*pValue = 88;

и ref version делают то же самое:

int Value = 50;
int &rValue = Value;

rValue = 88;

Какой из них лучше использовать? Спасибо.

Ответ 1

В этом случае они эквивалентны.

Неважно, что вы используете, и ни один из них не является "лучшим".

Если вы действительно хотите выбрать между ними, то ссылка, вероятно, более идиоматична. Я вообще придерживаюсь ссылок везде, где могу, потому что мне нравится OCD: они чувствуют себя "более жесткими", не могут быть перевязаны (с вами или без вас) и не требуют разыменования для получения значения.

Но я не знаю какого-либо общего согласия по этому вопросу в таких случаях.

Также обратите внимание, что они не могут скомпилироваться с тем же кодом, если ваша реализация не реализует ссылки с указателями, хотя я не знаю такой реализации, и вы все равно не заметили бы разницу.

Ответ 2

Указатель - это адрес ячейки памяти. Вы можете изменить значение этого адреса, чтобы указать на разные адреса памяти.

Ссылка - это псевдоним переменной. Вы можете назначить этот псевдоним только во время объявления. Вы не можете изменить, какая переменная ссылается на псевдоним после объявления.


Следующие присваивания указателей невозможны со ссылками.

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;

Как правило, я по умолчанию ссылаюсь на ссылки и использую указатели в тех местах, где ограничения на ссылки вызывают проблемы.

Ответ 3

Различия заключаются в следующем:

Ссылка является псевдонимом объекта и имеет тот же адрес, что и объект.

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;

Ответ 4

Мое правило состоит в том, чтобы использовать ссылку или ссылку на const, если не требуется указатель.

Ссылка не может быть пересмотрена, и она синтаксически чиста. Ссылка также гарантирует вам, что ссылка не NULL.

Я также могу использовать указатель для удобства при использовании массивов.

Ответ 5

Я согласен с ответом justin и хочу прояснить его с помощью крошечного примера.

Предположим, вы не совсем помните синтаксис геометрической библиотеки 2D-изображения: это

bool BooleanOr( const Bitmap & input1, const Bitmap & input2, Bitmap * output );

или это

bool BooleanOr( Bitmap * output, const Bitmap & input1, const Bitmap & input2 );

Если в вашей компании все используют указатели на выходы и константные ссылки для входов, практически невозможно сделать ошибку: когда вы видите такие вызовы, как

BooleanOr (thisBitmap, thatBitmap и другойBitmap);

вы сразу же знаете синтаксис.

Ответ 6

Отличные ответы здесь. Я хотел бы указать на 2 конкретных использования ссылок: -

Случай 1: При реализации operator[]. Этот оператор обычно должен возвращать то, что может использоваться как цель назначения. Пример: -

vector<int> v(20);
v[1] = 5; //The target of the assignment is the return value of operator []

Здесь operator [] возвращает ссылку элемента по указанному индексу в vector. Если бы 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;
  }
}