Это проблема с повторной привязкой ссылки? Я искал этот вопрос в Google, но не могу найти подходящих ответов на этот вопрос. Что заставило разработчиков C ++ сделать это именно так?
7 ответов
На большинство вопросов подобного рода отвечает Дизайн и эволюция C ++ Страуструпа. В этом случае см. Раздел §3.7 Ссылки:
В прошлом меня укусили ссылки на Algol68, где
r1=r2
может либо назначить черезr1
объекту, на который имеется ссылка, либо назначить новое ссылочное значение дляr1
(повторное связываниеr1
) в зависимости от типаr2
. Я хотел избежать подобных проблем в C ++.
Если вы хотите выполнять более сложные манипуляции с указателями в C ++, вы можете использовать указатели.
Бьярн Страуструп ввел в язык ссылки для поддержки ссылочных параметров («вызов по ссылке») для перегрузки оператора. Вам просто не нужно повторно связывать ссылочные параметры.
Если вам нужны «повторно связываемые ссылки», используйте указатели.
В C ++ ссылка - это просто другое имя объекта. Это не косвенное указание; вот почему вы не можете указать на другой объект.
Прежде всего, «ссылки» на самом деле являются константными указателями. Если вы хотите выполнить «повторную привязку», просто используйте обычные указатели.
Во-вторых, мы не можем повторно связать ссылки в нашем C ++.
ref1 = ref2; // It's not mean "rebinding" - it just modify the object which ref1 points.
Итак, нам нужно создать новый оператор, например этот
ref1 :=: ref2;
Это было бы грязным пунктом C ++, не так ли?
Одна проблема - это синтаксис. Как бы написать такую операцию? Вам придется создать совершенно новый оператор, чтобы устранить двусмысленность, - довольно большие вложения для того, что уже можно сделать с помощью указателей.
Внутренне 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)
}
Ссылки полезны, потому что они не поддерживают арифметику небезопасных указателей и никогда не будут иметь значение 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";
}
Похожие вопросы
Связанные вопросы
Новые вопросы
c++
C++ — это язык программирования общего назначения. Изначально он разрабатывался как расширение C и имел аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде, который будет скомпилирован с помощью компилятора C++. Используйте тег версии для вопросов, связанных с конкретной стандартной версией [C++11], [C++14], [C++17], [C++20] или [C++23]. и т.д.
std::reference_wrapper
:int x, y; auto r = ref(x);
Затем можно выполнить повторную привязку к y с помощьюr = ref(y)
. (Предполагаяusing std::ref
)