Должны ли постоянные конструкторы передаваться по ссылке или по значению? - PullRequest
1 голос
/ 08 января 2011

Когда значения const передаются в конструктор объекта, они должны быть переданы по ссылке или по значению?
Все учебные примеры конструкторов и инициализаторов передаются по значению, но мне это кажется неэффективным.

Если вы передаете по значению, а аргументы немедленно используются для инициализации переменной-члена, делаются ли две копии? Об этом автоматически позаботится компилятор?

class Point {
public:
    int x;
    int y;
    Point(const int _x, const int _y) : x(_x), y(_y) {}
};

int main() {
    const int a = 1, b = 2;
    Point p(a,b);
    Point q(3,5);

    cout << p.x << "," << p.y << endl;
    cout << q.x << "," << q.y << endl;
}

против

class Point {
public:
    int x;
    int y;
    Point(const int& _x, const int& _y) : x(_x), y(_y) {}
};

И компилировать, и делать то же самое, но что правильно?

Ответы [ 4 ]

2 голосов
/ 08 января 2011

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

1 голос
/ 08 января 2011

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

Передача по ссылке на const определенно имеет больше смысла для больших пользовательских типов, поскольку экономит потенциально дорогостоящую операцию копирования.

1 голос
/ 08 января 2011

Вы выбираете здесь между передачей ссылки и передачей значения. Обратите внимание, что эти сигнатуры функций идентичны.

Point( int x, int y );

Point( const int x, const int y );

С точки зрения вызывающего абонента не имеет значения, изменен ли параметр или нет, поскольку при передаче параметров по значению всегда выполняется копирование.

Вам нужно передать ссылку, если вы хотите инициализировать ссылку или указатель на этот фактический объект за пределами конструктора, если вам нужно только его значение, тогда передача по значению обычно предпочтительнее, если только стоимость копирования объекта не слишком высока. Для int это никогда не так.

0 голосов
/ 08 января 2011

Что-то простое, например, int, должно быть передано по значению.

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

Обратите внимание, что если ваш объект изменчив, то между передачей ссылки или копии есть семантическая разница - в первом случае вы увидите изменения в оригинале, а во втором - нет. Это верно, даже если вы объявили это как ссылку на const.

...