Каковы различия между переменной-указателем и ссылочной переменной в C ++? - PullRequest
2956 голосов
/ 12 сентября 2008

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

Но в чем различия?


Резюме из ответов и ссылок ниже:

  1. Указатель может быть переназначен любое количество раз, в то время как ссылка не может быть переназначена после привязки.
  2. Указатели не могут указывать нигде (NULL), тогда как ссылка всегда ссылается на объект.
  3. Вы не можете взять адрес ссылки, как вы можете с указателями.
  4. Там нет "ссылочной арифметики" (но вы можете взять адрес объекта, на который указывает ссылка, и сделать арифметику указателя на нем, как в &obj + 5).

Для уточнения заблуждения:

Стандарт C ++ очень осторожен, чтобы не указывать, как компилятор может реализовать ссылки, но каждый компилятор C ++ реализует ссылки как указатели. То есть декларация, такая как:

int &ri = i;

если он не оптимизирован полностью , выделяет тот же объем памяти в качестве указателя и размещает адрес i в это хранилище.

Итак, указатель и ссылка используют одинаковый объем памяти.

Как правило,

  • Используйте ссылки в параметрах функций и возвращаемых типах для предоставления полезных и самодокументируемых интерфейсов.
  • Используйте указатели для реализации алгоритмов и структур данных.

Интересно читать:

Ответы [ 35 ]

2 голосов
/ 19 октября 2017

Я всегда решаю это правило из C ++ Core Guidelines:

Предпочитать T * перед T &, когда допустимым параметром является «без аргумента»

1 голос
/ 02 августа 2018

Вы можете использовать разницу между ссылками и указателями, если вы следуете соглашению для аргументов, передаваемых в функцию. Ссылки Const предназначены для данных, передаваемых в функцию, а указатели - для данных, передаваемых из функции. В других языках вы можете явно указать это с помощью таких ключевых слов, как in и out. В C ++ вы можете объявить (по соглашению) эквивалент. Например,

void DoSomething(const Foo& thisIsAnInput, Foo* thisIsAnOutput)
{
   if (thisIsAnOuput)
      *thisIsAnOutput = thisIsAnInput;
}

Использование ссылок в качестве входных данных и указателей в качестве выходных данных является частью руководства по стилю Google .

0 голосов
/ 14 февраля 2019

В чем разница между операторами «&» и «*» в C & Является унарным оператором в C, который возвращает адрес памяти переданного операнда. Это также называется адресом оператора. <> * - это унарный оператор, который возвращает значение объекта, на которое указывает переменная-указатель. Это известно как значение оператора. Он также используется для объявления переменной указателя.

0 голосов
/ 16 января 2019

Кроме ответов здесь,

вы можете реализовать перегрузку операторов, используя ссылки:

my_point operator+(const my_point& a, const my_point& b)
{
  return { a.x + b.x, a.y + b.y };
}

Использование параметров в качестве значения создаст временные копии исходных аргументов, а использование указателей не вызовет эту функцию из-за арифметики указателей.

0 голосов
/ 27 апреля 2018

Тарын ♦ сказал:

Вы не можете взять адрес ссылки, как вы можете с указателями.

На самом деле вы можете.

Я цитирую ответ на другой вопрос :

FAQ по C ++ лучше всего говорит:

В отличие от указателя, когда ссылка привязана к объекту, она не может быть «переустановлена» к другому объекту. Сама ссылка не является объектом (она не имеет идентификатора; взятие адреса ссылки дает вам адрес референта; помните: ссылка является его референтом).

...