Различие аргумента функции как (const int &) и (int & a) в C ++ - PullRequest
8 голосов
/ 28 апреля 2010

Я знаю, что если вы напишите void имя_функции (int & a), то функция не будет делать локальную копию вашей переменной, переданной в качестве аргумента. В литературе также встречалось, что вы должны написать void имя_функции (const int & a), чтобы сказать компилятору, что я не хочу, чтобы переменная, переданная в качестве аргумента, была скопирована.

Итак, мой вопрос: в чем разница с этими двумя случаями (за исключением того, что const гарантирует, что переданная переменная не будет изменена функцией !!!) ???

Ответы [ 7 ]

11 голосов
/ 28 апреля 2010

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

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

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

void printr( int & i ) { std::cout << i << std::endl; }
void printcr( const int & i ) { std::cout << i << std::endl; }
int main() {
   int x = 10;
   const int y = 15;
   printr( x );
   //printr( y ); // passing y as non-const reference discards qualifiers
   //printr( 5 ); // cannot bind a non-const reference to a temporary
   printcr( x ); printcr( y ); printcr( 5 ); // all valid 
}
7 голосов
/ 28 апреля 2010

Итак, мой вопрос: в чем разница с этими двумя случаями ( за исключением того, что «const» гарантирует, что переменная проходы не будут изменены функция !!!) ???

То, что - это разница.

1 голос
/ 28 апреля 2010

Существует большая разница в параметрах, с которыми они могут работать, Допустим, у вас есть конструктор копирования для вашего класса из int,

customeclass(const  int & count){
  //this constructor is able to create a class from 5, 
  //I mean from RValue as well as from LValue
}
customeclass( int  & count){
  //this constructor is not able to create a class from 5, 
  //I mean only from LValue
}

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

1 голос
/ 28 апреля 2010

Вы правильно указали разницу. Вы также можете сформулировать это как:

Если вы хотите указать, что функция может изменить аргумент (т. Е. Для init_to_big_number( int& i ), указав аргумент с помощью (переменной) ссылки. В случае сомнений укажите его const.

Обратите внимание, что преимущество не копирования аргумента заключается в производительности, то есть для «дорогих» объектов. Для встроенных типов, таких как int, нет смысла писать void f( const int& i ). Передача ссылки на переменную такая же дорогая, как и передача значения.

0 голосов
/ 28 апреля 2010

опуская обсуждение производительности, пусть код говорит!

void foo(){
    const int i1 = 0;
    int i2 = 0;
    i1 = 123; //i gets red -> expression must be a modifiyble value
    i2 = 123;
}
//the following two functions are OK
void foo( int i ) {
    i = 123;
}
void foo( int & i ) {
    i = 123;
}
//in the following two functions i gets red
//already your IDE (VS) knows that i should not be changed
//and it forces you not to assign a value to i
//more over you can change the constness of one variable, in different functions
//in the function where i is defined it could be a variable
//in another function it could be constant 
void foo( const int i ) {
    i = 123; 
}
void foo( const int & i ) {
    i = 123; 
}

Использование «const» там, где это необходимо, имеет следующие преимущества: * вы можете изменить константу одной переменной i в разных функциях в функции, где я определен, это может быть переменная в другой функции это может быть постоянное значение. * Ваша IDE уже знает, что меня нельзя менять. и это заставляет вас не присваивать значение i

С уважением К сожалению

0 голосов
/ 28 апреля 2010

Я бы сказал, что

void cfunction_name(const X& a);

позволяет передать ссылку на временный объект следующим образом

X make_X();

function_name(make_X());

Пока

void function_name(X& a);

не может этого достичь. со следующей ошибкой ошибка: неверная инициализация неконстантной ссылки типа 'X &' из временного типа 'X'

0 голосов
/ 28 апреля 2010

Они используются для разных целей. Передача переменной с использованием const int& гарантирует, что вы получите семантику передачи по копии с гораздо лучшей производительностью. Вам гарантировано, что вызываемая функция (если она не делает какие-то безумные вещи, используя const_cast) не изменит переданный вами аргумент без создания копии. int& используется, когда обычно есть несколько возвращаемых значений из функции. В этом случае их можно использовать для сохранения результатов функции.

...