2015-11-04 5 views
0

Какой конструктор лучше для следующего класса?Аргумент, переданный значением или константой ссылки в конструкторе

struct Foo 
{ 
    Foo(const int& val):val_(val){} // constructor 1  
    Foo(int val):val_(val){} // constructor 2 
    int val_; 
}; 

без какой-либо оптимизации компилятора, сделать они копируют Вэла только один раз или же конструктор 2 создает дополнительную копию перед списком инициализации?

ответ

1

Если вызывается первый конструктор, переданный ему аргумент будет скопирован не. Аргумент val связывается с переданным аргументом (копия по ссылке).

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

оба конструкторы одинаковы в том, что они инициализации _val с val соответственно, и выполнить дополнительную копии по значению.

Таким образом, без каких-либо оптимизаций, это выглядит следующим образом:

            Copies 
const int& constructor   1 
int constructor       2 
+2

Это технически верно. Однако ссылка, вероятно, будет скомпилирована с указателем, а это означает, что * указатель * должен быть скопирован вместо значения. –

1

В принципе, конструктор 2 будет сделать копию дважды: первый раз по вызову, а второй раз на intialization. С другой стороны, вы понимаете, что ссылка - это не что иное, как указатель, и поскольку размер ссылочной переменной уменьшается до размера указателя, между конструкторами 1 и 2. нет сокращения затрат.

+0

Хотя одна из копий может быть удалена. – juanchopanza

+1

Да, это была моя догадка. Таким образом, вторая делает дополнительную копию без оптимизации. Так что для большого объекта лучше первое решение. Или, может быть, даже лучше, это передать int && напрямую. –

1

В общем, вам не нужно проходить мимо int переменные по ссылке const.

Реальный вопрос: почему вас это волнует? Будет только измеримая разность скоростей, если Foo построен внутри цикла с очень большим количеством итераций и это почти единственное, что происходит внутри этого цикла - очень маловероятно.

Так что просто используйте # 2. Не из-за эффективности, а потому, что это проще.

+0

int был только для поиска простоты. Используйте шаблонный аргумент вместо int. Мой вопрос касался количества копий, если компилятор не выполнил никакого копирования –