12

I was wondering - why is putting const (...)& in C++ a good idea? I found this code in some class tutorials. I understand that const is making something constant and it can't be changed, while & is passing it to the function. Why do both? If I can't change something, why should I be passing it to the function?

Here is an example:

class CVector {
      public:
        int x,y;
        CVector () {};
        CVector (int a,int b) : x(a), y(b) {}
        CVector operator + (const CVector&);
    };

    CVector CVector::operator+ (const CVector& param) { //example 
      CVector temp;
      temp.x = x + param.x;
      temp.y = y + param.y;
      return temp;
    }
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Igracx33
  • 389
  • 1
  • 3
  • 8
  • 1
    You can still read and you do, there: "temp.x = x + **param**.x;" – Yunnosch Jun 28 '17 at 06:42
  • 2
    Is your question "Why give a reference parameter, instead of copy by value, if the value of the referenced object is not (and cannot be) changed (because it is also const)?" – Yunnosch Jun 28 '17 at 06:45
  • I suggest you remove the (...). And maybe clarify the question: Are you asking about the & or the const? – starmole Jun 28 '17 at 07:13
  • Well, yes I don't understand why should I give reference parameter, instead of copy by value... – Igracx33 Jun 28 '17 at 07:22
  • Performance issues aside, some types of object *cannot be copied*. For those objects, passing by reference is the only way to give the called function access to them (well, you could pass a pointer or use a global variable, but we'll ignore those alternatives as they are very hack-ish) – Jeremy Friesner May 25 '23 at 19:58

3 Answers3

19

Even though the const is keeping you from changing the value of your parameter, it's better to send a reference to it, rather than send it by value, because, in large objects, sending it by value would require copying it first, which is not necessary when calling by reference

CIsForCookies
  • 12,097
  • 11
  • 59
  • 124
  • 3
    On the other hand if you would copy the value anyway inside the function (for example because you have to make temporary modifications), then you can want to remove the `const&` (an example [here](https://stackoverflow.com/a/24543391/1485885)). – cbuchart Jun 28 '17 at 06:52
  • 1
    @cbuchart of courese :) It's only better to send _const ... &_ when modifications are not intended – CIsForCookies Jun 28 '17 at 06:54
  • 1
    I think @cbuchart 's point was not modification but copying. Even if you won't modify the object but still make a copy of it, it's better to pass by value. – spectras Jun 28 '17 at 07:00
  • Copy and Swap can be implemented to take advantage of pass by value. No changes to parameter and you were going to copy it anyway... – user4581301 Jun 28 '17 at 07:05
  • 2
    Right, also, AFAIK, if you are using C++11 and the parameter happens to be an rvalue then you can benefit from moving semantics, therefore avoiding the copy completely (thing that won't happen if you use the `const&` plus a copy). – cbuchart Jun 28 '17 at 07:11
  • 1
    Tanks, I understand now. – Igracx33 Jun 28 '17 at 07:24
  • well, that's exactly what I said – CIsForCookies Sep 01 '19 at 10:25
3

It speeds up the code execution, it offers usage simplicity and it also ensures the caller that you can not change the value of the variable by setting const keyword. It maybe have some other benefits, but I think the performance is the main reason. In this article and related articles, there are many useful things about References in C++.

When you pass a parameter by const type & (pass by reference) like this:

void printStudent(const Student &s) 
{ 
    cout << s.name << "  " << s.address << "  " << s.rollNo; 
} 

int main(){
    Student s1;
    printStudent(s1);
    return 0;
}

Benefits are:

  1. Work easily with object(don't think about pointers)
  2. It does not copy the Student object(so it is fast)
  3. You can not create a new student and assign it to s variable. if you write s=new Student(); the compiler error will happen. So the caller can pass the variable with more confidence.
  4. The parameter can not be null.
gonidelis
  • 885
  • 10
  • 32
Mostafa Vatanpour
  • 1,328
  • 13
  • 18
2

Why const?: As it is known that const keyword makes the variable immutable(by programmer) in the particular part of code e.g. the function body.
Why &?: The & is used, in this context, for "pass the argument to the parameter as a reference" ( which we say call-by-reference ). Which in effect says: Don't create a new copy of the passed object ( or premitive type ). Since no new copy is creted so the passe argument is use and hence any change made to such parameter-variable will retain even after the function call is ended and will be reflected in the passed argument.

Now, coming to question "Why to use the both?". It is due to following reasons:

  1. To avoide unnecessory copy. For primitive data types call-by-value is not a problem but it is problem for non-primitive data types specially when non-primitive object is large

  2. If we wants to pass some rvalue reference as a function argument then it is necessory that respective parameter should be const-reference i.e. const (...)& otherwie it will be a compilation error. For example, in following code the line fun2( strValue1 + strValue2 ); will produce a compile time error. It can be seen in action here:

    #include <iostream>
    #include <string>
    
    void fun1( const std::string& strParm )
    {
        std::cout << "In [void fun1( const std::string& strParm )] :: " << strParm << std::endl;
    }
    
    
    void fun2( std::string& strParm )
    {
        std::cout << "In [void fun2( std::string& strParm )] :: " << strParm << std::endl;
    }
    
    int main() 
    {
        std::string strValue1 = "Hello ";
        std::string strValue2 = "World!!!";
    
        fun1( strValue1 + strValue2 );  // Ok
        fun2( strValue1 );              // Ok
        fun2( strValue1 + strValue2 );  // Compilation error
    
        return 0;
    }
    

Due to above facts, it is advised to use const-ref whenever possible.

cse
  • 4,066
  • 2
  • 20
  • 37
  • The compiler does not need `const` to see the function doesn't modify the object. `const` is only useful to enforce correctness, ie tell the compiler that if the developer directly modifies the object through the const reference, he is to be told off. – spectras Jun 28 '17 at 07:03
  • An object does not become magically immutable when passed by a `const` reference. It is more of a guarantee by the programmer it will not be altered. – too honest for this site Jun 28 '17 at 13:16
  • @Olaf It is stated that it is not changeable by programmer in that particular part of the code. I have modified the statement for appropriate meaning. – cse Jun 28 '17 at 13:21
  • It still is wrong. You can always enforce changing by applying a cast. – too honest for this site Jun 28 '17 at 13:28