Объем памяти в функциях C ++, возвращаемых по ссылке или значению?

Я пытаюсь уменьшить объем памяти приложения, разработанного в основном на C ++, и одна из вещей, на которые я обращал внимание, — возвращать особенно большую структуру данных по ссылкам, а не возвращать их по значению. Мне нужно было подтверждение на это. Например, скажем, у меня есть функции-члены в классе some_object следующее:

const some_type& get_some_type(...) {
...;
return ...;
}

против

const some_type get_some_type(...) {
...;
return ...;
}

Правильно ли я понимаю, что присвоение путем вызова последнего (возврат по значению) оставило бы две копии данных some_type в памяти в определенных точках во время выполнения приложения, хотя вызов первого (возврат по ссылке) позволяет избежать этого?

Еще одно усилие в рамках общей цели сокращения объема памяти заключалось в изменении самого определения some_type таким образом, чтобы исключить использование опции возврата по ссылке выше. В таком случае, так как some_type (который на самом деле является своего рода контейнером, скажем, данных типа data_type) используется внутри цикла следующим образом:

const some_type& = some_object->get_some_type(); // returns by ref. a large container
for(...) {
...;
data_type = some_type.at(...);
...;
}

Я предполагаю, что если мы будем вынуждены использовать приведенный выше возврат по значению, то мне нужно будет внести изменения следующим образом, введя новую функцию get_some_type_at чтобы получить элемент контейнера по значению (есть ли недостатки в этом, о которых я должен знать, скажем, по производительности?):

for(...) {
...;
data_type = some_object->get_some_type_at(...); // returns by value a small object
...;
}

Опять же, я в основном ищу подтверждение этих аспектов. Но детали и идеи наиболее ценны. Спасибо за ваше время и интерес!

0

Решение

Большинство хороших компиляторов реализуют оптимизация возвращаемого значения, так что вам не нужно беспокоиться о ненужном построении объектов копирования.

Следовательно, выберите

some_type get_some_type(...) {
...;
return ...;
}

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

(Благодарность juanchopanza; также опустите возврат объекта const; объяснение в комментариях.)

Увидеть http://en.wikipedia.org/wiki/Return_value_optimization Больше подробностей; Бессмысленно дублировать это здесь.

3

Другие решения

Верно ли мое понимание того, что присвоение путем вызова последнего (возврат по значению) оставило бы две копии данных some_type в памяти в определенных точках во время выполнения приложения, в то время как вызывающий первый (возврат по ссылке) избегает этого?

С современным компилятором шансы на это довольно невелики. Стандарт специально благословляет то, что называется оптимизацией возвращаемого значения (и названной оптимизацией возвращаемого значения), чтобы позволить компилятору избежать создания дополнительных копий в подобном случае. Каждый достаточно современный компилятор, о котором я знаю, включает эту оптимизацию. В некоторых случаях (например, GCC) они делают эту оптимизацию четное когда вы говорите компилятору не сделать оптимизацию. С включенной оптимизацией вам нужно будет найти что-то около 10 лет (а может и больше), чтобы найти компилятор, который этого не делал.

В C ++ 11 добавлена ​​возможность «переместить», чтобы сделать еще больше для решения проблемы, с которой вы столкнулись, даже когда вы возвращаете большой объект по значению.

Итог: мне кажется, что вы ищете не в том месте — вы можете рассмотреть возможность добавления явного конструктора перемещения (и, возможно, оператора перемещения) в ваш класс, но в целом вы можете просто вернуть по значению и будь счастлив.

2

По вопросам рекламы [email protected]