Это проблема с повторной привязкой ссылки? Я искал этот вопрос в Google, но не могу найти подходящих ответов на этот вопрос. Что заставило разработчиков C ++ сделать это именно так?

c++
14
lqr 20 Ноя 2014 в 13:51
1
Потому что это не имеет смысла. Когда вы назначаете ссылку, вы присваиваете самому объекту.
 – 
The Paramagnetic Croissant
20 Ноя 2014 в 13:54
6
Потому что у нас есть указатели, и нам не нужно одно и то же дважды.
 – 
Ivan Aksamentov - Drop
20 Ноя 2014 в 14:03
1
Обратите внимание, что для повторной привязки ссылок вы можете использовать std::reference_wrapper : int x, y; auto r = ref(x); Затем можно выполнить повторную привязку к y с помощью r = ref(y). (Предполагая using std::ref)
 – 
leemes
20 Ноя 2014 в 14:20
1
Ссылки Java относятся к объектам (т.е. вещам), ссылки C ++ относятся к переменным (т. Е. Местам, в которых хранятся вещи). Это разные концепции, которые имеют одно имя.
 – 
molbdnilo
20 Ноя 2014 в 14:44
2
@molbdnilo: Нет. Ссылки C ++ определенно относятся к объектам.
 – 
Benjamin Lindley
20 Ноя 2014 в 14:48

7 ответов

Лучший ответ

На большинство вопросов подобного рода отвечает Дизайн и эволюция C ++ Страуструпа. В этом случае см. Раздел §3.7 Ссылки:

В прошлом меня укусили ссылки на Algol68, где r1=r2 может либо назначить через r1 объекту, на который имеется ссылка, либо назначить новое ссылочное значение для r1 (повторное связывание r1) в зависимости от типа r2. Я хотел избежать подобных проблем в C ++.
Если вы хотите выполнять более сложные манипуляции с указателями в C ++, вы можете использовать указатели.

18
Jonathan Wakely 20 Ноя 2014 в 14:02

Бьярн Страуструп ввел в язык ссылки для поддержки ссылочных параметров («вызов по ссылке») для перегрузки оператора. Вам просто не нужно повторно связывать ссылочные параметры.

Если вам нужны «повторно связываемые ссылки», используйте указатели.

6
fredoverflow 20 Ноя 2014 в 13:57

В C ++ ссылка - это просто другое имя объекта. Это не косвенное указание; вот почему вы не можете указать на другой объект.

2
axiac 20 Ноя 2014 в 13:56
С механической точки зрения это может быть косвенное обращение (например, передача по ссылке). Но синтаксически шаг для определения ссылки не требуется, в отличие от указателей (чтобы звучало странно, ссылка всегда синтаксически отменяется).
 – 
uvsmtid
3 Май 2020 в 17:37

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

Во-вторых, мы не можем повторно связать ссылки в нашем C ++.

ref1 = ref2; // It's not mean "rebinding" - it just modify the object which ref1 points.

Итак, нам нужно создать новый оператор, например этот

ref1 :=: ref2;

Это было бы грязным пунктом C ++, не так ли?

1
ikh 20 Ноя 2014 в 14:00
Спасибо брат. Ваш ответ очень полезен!
 – 
lqr
20 Ноя 2014 в 14:11
2
Оператор :=: считается "оператором обмена" в черновик N3553.
 – 
leemes
20 Ноя 2014 в 14:14

Одна проблема - это синтаксис. Как бы написать такую ​​операцию? Вам придется создать совершенно новый оператор, чтобы устранить двусмысленность, - довольно большие вложения для того, что уже можно сделать с помощью указателей.

0
glank 20 Ноя 2014 в 14:05

Внутренне reference представляет собой не что иное, как const pointer (как только этому указателю будет присвоен адрес, вы можете изменить его простым способом).

int& r = a; // int* const r = &a;

Пример кода ниже объясняет, что будет происходить за экраном.

int main() {
    int a = 10;
    int b = 20;

    int& r = a;          // = [int* const r = &a;]
    r = b;               // = [*r = b] value update. NOT address update [r = &b]
    ++r;                 // = [++*r]
    cout << r << a << b; // 21 21 20 (bcos r is NOT rebinded to b)
}
0
SridharKritha 20 Апр 2022 в 19:09

Ссылки полезны, потому что они не поддерживают арифметику небезопасных указателей и никогда не будут иметь значение NULL. С другой стороны, указатели могут быть повторно привязаны и могут быть помещены в контейнеры STL. Компромисс со всеми этими полезными свойствами - std :: reference_wrapper:

#include <functional>
#include <iostream>
#include <string>

int main() {
  std::string s1 = "my", s2 = "strings";

  auto r = std::ref(s1);  // bind

  // use r.get() to access the referenced object
  std::cout << '\'' << r.get() << "' has " << r.get().size() << " characters\n";

  r = s2;  // rebind

  // use the other object
  std::cout << '\'' << r.get() << "' has " << r.get().size() << " characters\n";
}
1
Ayxan Haqverdili 17 Окт 2021 в 11:19