Ответ 1
Ссылки не переустанавливаются в С++. Это означает, что после их инициализации вы не сможете переназначить их. Вместо этого любое присвоение фактически включает упомянутый объект. Итак, в вашем коде
foo1 = bar();
std::map< std::string, std::string >& foo2 = bar();
первая строка вызывает std::map::operator=
объекта, который был передан как параметр myFunc
. После этого foo1
неподвижные объекты ссылаются на тот же объект, но его значение (например, какие элементы, которые он содержит) может быть очень хорошо изменено.
Обратите внимание, что вторая строка не является присвоением, если есть какие-либо сомнения в том, что это было в вашем уме. Вместо этого это инициализация. Так как тип возврата бара на самом деле std::map<std::string, std::string> const&
, он не может привязываться к std::map<std::string, std::string>&
, поэтому он компилирует ошибку.
Чтобы расширить "философскую" сторону вещей, ссылки на С++ разработаны настолько, насколько это возможно, и не существуют как объекты. Это использует значение термина С++ Standard (оно не связано с ООП): это означает, что, например, ссылочные типы не имеют размера. Вместо этого sizeof(T&) == sizeof(T)
. Аналогично, ссылки не имеют адресов, и невозможно сформировать указатель или ссылку на ссылку: данный int& ref = i;
, затем &ref == &i
.
Таким образом, ссылки предназначены для использования так, как если бы упомянутые объекты использовались сами. Единственное, что связано с привязкой к ссылке на всю жизнь ссылки, это ее инициализация: что она может связывать и что она означает с точки зрения времени жизни.