Маленькие простые структуры должны быть переданы ссылкой константы?

Мне всегда преподавали, что нетипы примитивов должны быть переданы ссылкой константы, а не значением, если это возможно, т.е.:

void foo(std::string str);//bad
void foo(const std::string &str);//good

Но я думал сегодня, что, возможно, на самом деле некоторые простые определяемые пользователем типы могут на самом деле быть лучше переданы значением, например:

class Vector2
{
public:
    float x, y;
    ...constructors, operators overloads, utility methods, etc...
};

void foo(Vector2 pos);
void foo(const Vector2 &pos);//is this really better than by value?
void foo(float x, float y);//after all isn't by value effectively doing this?

Моя мысль - то, что путем передачи Vector2 ссылкой, это на самом деле более дорого, чем передача значением, так как компилятор теперь использует указатель и разыменовывает для доступа к версии Vector2 &pos константы?

Имеет место это? Простые объекты лучше всего от переданного значением? Где линия должна быть проведена?

18
задан Fire Lancer 22 July 2010 в 22:59
поделиться

6 ответов

Да, простые объекты должны передаваться по значению. Линия должна быть проведена в соответствии с архитектурой. Если есть сомнения, профиль.

8
ответ дан 30 November 2019 в 09:27
поделиться

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

В мире C# вы принимаете это решение, выбирая, сделать ли что-то классом или структурой. Классы используют семантику ссылок, а структуры - семантику значений. Все, что я когда-либо читал, говорит о том, что обычно следует выбирать класс, если только он не очень мал, т.е. порядка 16 байт. Если вы ищете границу, когда в C++ следует передавать по значению, а не по const-ссылке, то 16 байт кажется разумным порогом.

1
ответ дан 30 November 2019 в 09:27
поделиться

Просто в качестве правила я передаю любой объект, который не является базовым типом данных C, по ссылке const. Так гораздо легче запомнить.

1
ответ дан 30 November 2019 в 09:27
поделиться

Более старый, но внятный анализ особенностей передачи параметров можно найти на http://www.ddj.com/184403855. Конечно, c++0x избавляет от многих подобных проблем с помощью семантики перемещения, но в статье приводится много обоснований того, почему семантика перемещения желательна.

1
ответ дан 30 November 2019 в 09:27
поделиться

Я считаю, что передача Vector2 по ссылке на самом деле дороже, чем передача по значению, поскольку теперь компилятор использует указатель и разыменование для доступа к версии const Vector2 & pos

Было бы верно, если бы вы передали объект, где size_of (object) . Например, char const & может быть дороже, чем char

0
ответ дан 30 November 2019 в 09:27
поделиться

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

1
ответ дан 30 November 2019 в 09:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: