1

I was watching a video and saw this code:

class Dog {
    public:
        Dog() : age(3), name("dummy") {} 
        void setAge(const int &a) { age = a; } 
    private:
        int age;
        std::string name;
};

I was curious about the function signature for setAge because I've never used const as a function parameter. I've looked at several related answers, but none that seemed to answer my question.

In such an elementary example, it's hard to see the benefit of passing a const reference to a function.

Is there any reason why you'd want to make the reference a const? The only application I could think of is in embedded programming when making a copy of a variable could waste precious space.

Are there any simple examples, perhaps, where the impact is seen easily of passing a const reference?

erip
  • 16,374
  • 11
  • 66
  • 121
  • To confirm, your question is "why use `const int &a` rather than `int a` as an argument?"? – Oliver Charlesworth May 31 '15 at 13:38
  • Otherwise, the routine would be able to change the passed `int` -- and in fact, it should be expected to do so. See the whole thing about [const correctness](http://www.parashift.com/c++-faq/const-correctness.html). – davidhigh May 31 '15 at 13:47
  • @erip Funny, because you're asking what the point of making the reference `const` is. Which suggests you're asking about `int&` vs. `const int&`. – juanchopanza May 31 '15 at 13:51
  • @juanchopanza If you pass by value, you are only making changes to the *copy*, so does it really matter? I guess you couldn't make a change to the original object anyway. – erip May 31 '15 at 13:53
  • What I am trying to say is that your question isn't very clear. – juanchopanza May 31 '15 at 13:55

4 Answers4

6

Making a copy of a variable wastes precious space and wastes precious time, which is why avoiding unnecessary copies is something to worry about in any kind of programming, not just embedded one. For this reason using const T & references for passing read-only parameters has always been an idiom in C++.

However, it is usually reserved for passing in "heavy" objects, i.e. objects that that are relatively expensive to copy. Using it with scalar types (as in your example) makes little or no sense.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Yes, this makes sense. I was thinking for some constant amount of copies it would be essentially useless. Passing a reference to an array, `std::vector`, or any other generic object would make much more sense. – erip May 31 '15 at 13:55
6

Consider the following three examples:

(i)   void setAge(int &a) { age = a; }
(ii)  void setAge(const int &a) { age = a; } 
(iii) void setAge(int a) { age = a; } 

Further think of your class as an encapsulated object, that is the outside world in general doesn't know what's going on inside.

Then, using case (i), the caller cannot know that a has not been changed afterwards.

int a=3;
dog.setAge(a);  //case (i): what is "a" afterwards?

One does not know what value a holds after the function call -- in fact, the function signature tells the caller that a change of a is likely to occur.

On the other hand, by using variant (ii), you again pass the object via reference, that is you do not make a copy, but tell the function the memory address where it can go to accss the parameter. In contrast to case (i), now you ensure the caller "nothing is going to happen to your parameter". That is, you can safely work with the parameter afterwards and be assured it has still the same value as before (--at least in principle, as also bad things like a const_cast might happen inside the function).

Finally, in case (iii), one makes a copy of the int and uses that inside the function. For built-in types like int, that is in fact the preferred way to pass function parameters. However, it might be uneffective if the object is expensive-to-copy.

With regard to the whole const correctness-topic, see here.

davidhigh
  • 14,652
  • 2
  • 44
  • 75
3

Consider an object which has a large memory footprint. You need to pass it to a function - a function which will only extract some information without changing the object in anyway possible. A const reference is a good candidate in such a case.

std::vector can be an example, a Matrix object is another example.

a_pradhan
  • 3,285
  • 1
  • 18
  • 23
3
void setAge(const int &a) { age = a; }

You are passing a const int reference, you don't intend to modify the value a inside function setAge.

void setAge(int &a) { age = a; }

You are passing a int reference, you don't care does function setAge modify the value a inside function setAge.

Doing const correctness is a good programming practice here as a practice of better interface definition. First function signature convey the message very clearly, and second one is vague compared to first one.

You can read more about const correctness here https://isocpp.org/wiki/faq/const-correctness#overview-const

Steephen
  • 14,645
  • 7
  • 40
  • 47