Что такое постоянная ссылка?(не ссылка на константу) - PullRequest
56 голосов
/ 14 сентября 2011

Довольно теоретический вопрос ... Почему константные ссылки не ведут себя так же, как константные указатели, и я действительно могу изменить объект, на который они указывают?Они действительно кажутся еще одним простым объявлением переменной.Зачем мне их использовать?Это короткий пример, который я запускаю, который компилируется и запускается без ошибок:

int main (){
    int i=0;
    int y=1;    
    int&const icr=i;
    icr=y;          // Can change the object it is pointing to so it's not like a const pointer...
    icr=99;         // Can assign another value but the value is not assigned to y...
    int x=9;
    icr=x;
    cout<<"icr: "<<icr<<", y:"<<y<<endl; 
}

Ответы [ 7 ]

77 голосов
/ 15 сентября 2011

Самый ясный ответ. Имеет ли смысл «X & const x»?

Нет, это ерунда

Чтобы узнать, что означает вышеуказанное объявление, прочитайте его справа налево: «Х - это константная ссылка на Х». Но это избыточно - ссылки всегда постоянны, в том смысле, что вы никогда не сможете переустановить ссылку чтобы он ссылался на другой объект. Никогда. С или без Const.

Другими словами, «X & const x» функционально эквивалентно «X & x». Поскольку вы ничего не получаете, добавляя const после &, вы не стоит добавлять это: это смущает людей - const сделает некоторые люди думают, что X - это const, как если бы вы сказали «const X & x».

47 голосов
/ 14 сентября 2011

Оператор icr=y; не делает ссылку на y; он присваивает значение y переменной, на которую ссылается icr, i.

Ссылки по своей природе const, то есть вы не можете изменить то, к чему они относятся. Существуют «const ссылки», которые действительно являются «ссылками на const», то есть вы не можете изменить значение объекта, на который они ссылаются. Они объявлены const int& или int const&, а не int& const.

25 голосов
/ 14 сентября 2011

Что такое постоянная ссылка (не ссылка на постоянную)
A Ссылка на константу на самом деле является ссылкой на константу .

Ссылка на константу / Ссылка на константу обозначается:

int const &i = j; //or Alternatively
const int &i = j;
i = 1;            //Compilation Error

В основном это означает, что вы не можете изменить значение объекта типа, на который ссылается Ссылка.
Например:
Попытка изменить значение (присвоить 1) переменной j через константную ссылку, i приведет к ошибке:

назначение ссылки только для чтения read i ’


icr=y;          // Can change the object it is pointing to so it's not like a const pointer...
icr=99;

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

Первый оператор присваивает значение y i
Второй оператор присваивает значение 99 i

3 голосов
/ 03 сентября 2018

Этот код некорректен:

int&const icr=i;

Ссылка: C ++ 17 [dcl.ref] / 1:

Cv-квалифицированные ссылки плохо сформированы, за исключением случаев, когда cv-квалификаторы введены с помощью typedef-name или decltype-спецификатор , в этом случае cv-квалификаторы игнорируются.

Это правило присутствует во всех стандартизированных версиях C ++. Потому что код плохо сформирован:

  • вы не должны его использовать, а
  • нет связанного поведения.

Компилятор должен отклонить программу; и если это не так, поведение исполняемого файла полностью не определено.

NB: Не уверен, что ни один из других ответов не упомянул это еще ... никто не имеет доступа к компилятору?

3 голосов
/ 14 сентября 2011

Под "постоянной ссылкой" я предполагаю, что вы действительно имеете в виду "ссылку на постоянные данные".С другой стороны, указатели могут быть указателем на константу (сам указатель является константой, а не данными, на которые он указывает), указателем на постоянные данные или и тем, и другим.

2 голосов
/ 23 января 2019

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

int &ref = obj;

После того, как вы инициализировали ссылку с объектом, вы не можете отсоединить эту ссылку с ее объектом, на который она ссылается. Ссылка работает так же, как псевдоним.

Когда вы объявляете ссылку const, это не что иное, как ссылка, которая ссылается на объект const.

const int &ref = obj;

Приведенные выше декларативные предложения, такие как const и int, определяют доступные функции объекта, на которые будет ссылаться ссылка. Чтобы быть более понятным, я хочу показать вам pointer эквивалент ссылки const;

const int *const ptr = &obj;

Таким образом, приведенная выше строка кода эквивалентна const ссылке в своем рабочем виде. Кроме того , есть еще один момент, о котором я хотел бы упомянуть;

Ссылка должна быть инициализирована только с объектом

Поэтому, когда вы сделаете это, вы получите ошибку;

int  &r = 0; // Error: a nonconst reference cannot be initialized to a literal

Это правило имеет одно исключение. Если ссылка объявлена ​​как const, вы также можете инициализировать ее литералами;

const int  &r = 0; // a valid approach
0 голосов
/ 03 сентября 2018

Сначала я думаю, int&const icr=i; - это просто int& icr = i, модификатор 'const' не имеет смысла (это просто означает, что вы не можете сделать ссылку ссылкой на другую переменную).

const int x = 10;
// int& const y = x; // Compiler error here

Во-вторых, постоянная ссылкапросто означает, что вы не можете изменить значение переменной через ссылку.

const int x = 10;
const int& y = x;
//y = 20; // Compiler error here

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

float x = 10;
const int& y = x;
const int& z = y + 10;
cout << (long long)&x << endl; //print 348791766212
cout << (long long)&y << endl; //print 348791766276
cout << (long long)&z << endl; //print 348791766340
...