Проблема с константными ссылками и временными объектами - PullRequest
1 голос
/ 19 марта 2020

Я понял из C ++ Primer, что когда я связываю константную ссылку с неконстантным объектом, ссылка привязывается к временному объекту, значение которого является неконстантным объектом.

int a = 1;
const int &b = a;
a = 2;
std::cout<<b;

В соответствии с тем, что я понял, будет создан временный const int объект, значение которого a и с ним будет инициализировано b, так что, как если бы я написал этот код :

int a = 1;
const int x = a;
const int &b = x;
a = 2;
std::cout<<b;

Первый код печатает 2, а второй печатает 1. Почему? Почему значение константной ссылки b изменилось с изменением a, хотя оно фактически привязано к временному константному объекту, а не к a напрямую?

Ответы [ 4 ]

4 голосов
/ 19 марта 2020

Вы путаете две разные вещи, которые говорит праймер C ++.

Во-первых, вы используете термин «константная ссылка» для обозначения ссылки, которая сама является константой. Это не то, что праймер C ++ подразумевает под термином «константная ссылка». Как говорится:

ТЕРМИНОЛОГИЯ: CONST REFERENCE - ЭТО ССЫЛКА НА CONST
C ++ программисты склонны к большему употреблению термина const reference . Строго говоря, под « const reference » подразумевается « ссылка на const ». ... Такое использование настолько распространено, что мы будем следовать ему и в этой книге.

Во-вторых, вы путаете примеры и правила, относящиеся к различным базовым типам (double и const int), с примеры, включающие один и тот же базовый тип (int и const int).

Попробуйте получить эффект, который вы описываете:

double a = 42.0;
const int &b = a;
2 голосов
/ 19 марта 2020

Я понял, будет создан временный объект const int, значением которого является a и будет инициализирован b,

Вы ошибаетесь. В этом фрагменте кода не создается ни временный объект

int a = 1;
const int &b = a;

Более того, в Стандарте C ++ даже не указано, выделена ли память для ссылки b.

Следует учитывать ссылку b в качестве псевдонима для переменной a.

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

a = 2;

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

b = 2;

. Вы можете использовать ссылку для изменения значения объекта a, если ссылка была объявлена ​​как

int &b = a;

В этом случае результат этих двух операторов

a = 2;

и

b = 2;

будет эквивалентен.

Что касается этого фрагмента кода

int a = 1;
const int x = a;
const int &b = x;
a = 2;
std::cout<<b;

, то константе x присваивается копия значения переменной a. x и a - два разных объекта, которые занимают разные объемы памяти.

Ссылка b объявляется как ссылка на объект x.

const int &b = x;

Таким образом, изменение объекта a не влияет на значение константы x. Константа x не может быть изменена ни напрямую, ни с помощью ссылки b.

2 голосов
/ 19 марта 2020
int a = 1;
const int x = a;  // x is a copy of a
const int &b = x;  // b is a reference to x, not a
a = 2;
std::cout<<b;

Во втором фрагменте b является ссылкой на x. (Обратите внимание, что x НЕ является ссылкой на a). Таким образом, изменение а не меняет х, и поэтому не меняет б.

0 голосов
/ 19 марта 2020

Hello @ Mason,

int a = 1;
const int &b = a;
a = 2;
std::cout<<b;

Здесь переменная b связана с постоянным адресом или «ссылкой», то есть a. Вы можете делать все, что вы хотите, чтобы a, но если вы должны были сделать:

int c = 7;
&b = c;

т.е. , измените ссылку на b, вы получите ошибку. b будет содержать любое значение, равное a. Вот как работает передача / вызов по ссылке.

int a = 1;
const int x = a;
const int &b = x;
a = 2;
std::cout<<b;

Здесь, как сказал @cigien,

Во втором фрагменте b - это ссылка на x. (Обратите внимание, что x НЕ является ссылкой на a). Таким образом, изменение a не меняет x, и поэтому не меняет b.

ваша переменная b не имеет отношения к a. Он связан только с x так же, как в первом коде он был a. Здесь любое изменение a не влияет на x. Следовательно, это оправдывает ответ;)

Best.

...