views:

262

answers:

7

I know that if you write void function_name(int& a), then function will not do local copy of your variable passed as argument. Also have met in literature that you should write void function_name(const int & a) in order to say compiler, that I dont want the variable passed as argument to be copied.

So my question: what is the difference with this two cases (except that "const" enshures that the variable passes will not be changed by function!!!)???

+6  A: 

So my question: what is the difference with this two cases (except that "const" enshures that the variable passes will not be changed by function!!!)???

That is the difference.

Alex
I meen from the aspect of copy.
Narek
@Narek: the `const` doesn't affect whether or not a copy is performed. Passing by reference (`const` or not) will avoid a copy. Passing by value (not using a reference) will cause a copy, whether the parameter is `const` or not. Using a `const` reference parameter for an `int` is generally considered unnecessary, since passing by value has no additional cost in that case.
Michael Burr
@Michael: and what about `const int` vs `int` ?
kriss
the `int` is passed by copy both times, the former ensuring that the function doesn't change it. (But this doesn't matter much for the caller, since it only can change its copy of it). Though this can prevent accidental change, in the same way `const` is used when declaring local variables.
Alex
+5  A: 

You should use const in the signature whenever you do not need to write. Adding const to the signature has two effects: it tells the compiler that you want it to check and guarantee that you do not change that argument inside your function. The second effect is that enables external code to use your function passing objects that are themselves constant (and temporaries), enabling more uses of the same function.

At the same time, the const keyword is an important part of the documentation of your function/method: the function signature is explicitly saying what you intend to do with the argument, and whether it is safe to pass an object that is part of another object's invariants into your function: you are being explicit in that you will not mess with their object.

Using const forces a more strict set of requirements in your code (the function): you cannot modify the object, but at the same time is less restrictive in your callers, making your code more reusable.

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 
}
David Rodríguez - dribeas
+1  A: 

You state the difference right. You may also formulate it as:

If you want to specify that the function may change the argument (i.e. for init_to_big_number( int& i ) by specifying the argument by (variable) reference. When in doubt, specify it const.

Note that the benefit of not copying the argument is in performance, i.e. for 'expensive' objects. For built-in types like int it makes no sense to write void f( const int& i ). Passing the reference to the variable is just as expensive as passing the value.

xtofl
A: 

They are used for different purposes. Passing a variable using const int& ensures you get the pass-by-copy semantics with much better performance. You are guaranteed that the called function (unless it does some crazy things using const_cast) will not modify your passed argument without creating a copy. int& is used when there are generally multiple return values from a function. In that case these can be used hold the results of the function.

Naveen
Charles Bailey
+1  A: 

There is a big difference in terms of parameter they could operate on, Say you have a copy constructor for your class from 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
}

The const version can essentially operate on temporary values and non constant version could not operate on temporary, you would easily face issue when you miss out const where it is needed and use STL, but you get weired error telling it could not find the version that takes temporary. I recommend use const where ever you can.

yesraaj
A: 

I would say that

void cfunction_name(const X& a);

allows me to pass a reference to temporary object as follows

X make_X();

function_name(make_X());

While

void function_name(X& a);

fails to achieve this. with the following error error: invalid initialization of non-const reference of type 'X&' from a temporary of type 'X'

Vicente Botet Escriba
A: 

Hi,

leaving out the performance discussion, let the code speak!

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; 
}

using "const" where it is needed has the following benefits: * you can change the constness of one variable i, in different functions in the function where i is defined it could be a variable in another function it could be constant value. * already your IDE knows that i should not be changed. and it forces you not to assign a value to i

regards Oops

Oops