2016-03-28 2 views
1

Я изо всех сил пытаюсь понять rvalues ​​на C++. В частности, я не понимаю, где они выделены и почему они должны быть неизменными. Предположим, у меня есть следующий код:Выделение и неизменность ссылок на rvalues ​​в C++

std::string str = std::string(); 
    const std::string& sref = std::string(); 

Первая строка создает объект в стеке. Объект str является изменяемым объектом, и я могу делать все, что захочу. Выражение справа от присваивания равно rvalue, а str - значение lvalue, насколько я понял.

Вторая строка создает объект в текущем стеке функций (я полагаю) и возвращает ссылку на константу. Созданный объект неизменен. Опять же, правая часть задания - это rvalue, но на этот раз я получил ссылку на rvalue. Вся ссылка, для rvalue ДОЛЖНА быть const, потому что согласно стандарту C++ вы не можете изменить значение rvalue. Первый вопрос, где sref выделено в текущем стеке функций? Почему это должно быть неизменным? Я действительно не понимаю, почему, если объект находится в стеке, я не могу его просто изменить.

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

const std::string& ref_1 = std::string(); 
const std::string& ref_2 = std::string(); 

следующие два ссылок, ссылающихся на один и тот же объект в C++?

+0

C не C++ не является «C с классами». – Olaf

+1

@Olaf: Где OP предположил, что это так? –

+0

@Olaf Я не понимаю ваш комментарий? Как это связано с моим вопросом? Где я упоминаю C? –

ответ

2

Не имеет значения, где они выделены. Где-то в памяти на вашем компьютере, или, может быть, совсем нет, если они оптимизированы. Не беспокойтесь об этом.

They're not immutable — вы можете изменить их, если хотите (попробуйте std::string().append('!')); просто вам разрешено привязывать временную ссылку , если это ссылка на const. И если вы не привязываете его к ссылке, вы не можете называть ее позже, чтобы что-либо сделать с ней.

This limitation was intended to prevent programmer mistakes, так как изменение временного обычно бессмысленно, хотя Visual Studio расслабляет это ограничение. Тем не менее, you can still make use of this lifetime-extension without const by using an rvalue reference:

std::string&& ref = std::string(); 
ref.append('!'); 
std::cout << ref << '\n'; 

Почему бы вы это сделали? Кто знает.

Что касается вашего окончательного вопроса (один вопрос на вопрос, пожалуйста, в следующий раз), нет, эти две ссылки относятся к двум, несвязанным, временным объектам std::string.

+0

Я думаю, вам нужно больше объяснить «продление срока жизни временного объекта путем привязки к константной ссылке», к OP. – user3528438

+0

@ user3528438: Нет, OP может прочитать книгу на C++ для более подробной информации. Или просто выполните поиск по SO для миллионов предыдущих вопросов по этому вопросу. –

+0

Благодарим вас за ответ. Просто мне нужно разъяснение. Правильно ли ссылаться на результирующий строковый объект как на временный объект? –

Смежные вопросы