8

What is the purpose for the "const" keyword for a reference if the object it is referencing is not a const object? Is there any difference between what r1 and r2 does (below)?

int i = 42; // non const object
const int &r1 = i; // const reference to non const object

int j = 25; // non const object
int &r2 = j; // non const reference to non const object

Here's a quote from CPP Primer 5th:

"C++ programmers tend to abbreviate the phrase “reference to const” as “const reference.” This abbreviation makes sense—if you remember that it is an abbreviation. Technically speaking, there are no const references. A reference is not an object, so we cannot make a reference itself const. Indeed, because there is no way to make a reference refer to a different object, in some sense all references are const. Whether a reference refers to a const or nonconst type affects what we can do with that reference, not whether we can alter the binding of the reference itself."

I think this means that making a reference a "const" when it is referenced to a non const object does absolutely nothing. We may as well take that const keyword out when defining that reference.

Asking this question here for confirmation.

Edit: Looks like my initial conjecture is wrong. I understand now that a const reference to a non const object does have a purpose: to prevent the reference from modifying the object. The non const object can still be modified by other means but not by this const reference.

Thanks all.

Steve Cho
  • 431
  • 2
  • 5
  • 10
  • 2
    "I think this means that making a reference a "const" when it is referenced to a non const object does absolutely nothing." you think wrong – Slava Aug 30 '18 at 18:45

6 Answers6

17

"What is the purpose for the "const" keyword for a reference if the object it is referencing is not a const object?" The purpose is to prevent that reference being used to modify the object it is referencing.

int i = 42; // non const object
const int &r1 = i; // const reference to non const object
r1 = 6 * 9; // error, r1 cannot be used to modify i;
Tim Randall
  • 4,040
  • 1
  • 17
  • 39
  • @Caleth right, but what it said originally that it prevents that object to be modified in general. Now the answer is corrected so I removed my comment. – Slava Oct 31 '19 at 14:51
  • How does this work with something like `const string&` or `const vector<...>&`? Is there some magic in C++ that prevents you from using the methods on those objects to modify them? Or does it just mean you can't completely reassign them? – Thomas Ahle Oct 21 '21 at 19:50
  • @ThomasAhle there's no magic, just the compiler issuing errors if you try to write code that calls non-`const` methods on `const` objects. Look at an include file like , for example, and you'll see a list of methods, some of which are labeled `const` and some are not. The former are guaranteed not to modify the object. The latter cannot be called on a `const` object, or through a `const` reference or pointer. – Tim Randall Oct 25 '21 at 15:41
6

To understand it better you can look into difference between const pointer and pointer to a const data:

int i, j;
const int *p1 = &i; // pointer to constant int
int *const p2 = &i; // constant pointer to int

*p1 = 0; // error, p1 points to const int
*p2 = 0; // it is fine sets i to 0

 p1 = &j; // fine p1 now points to anbother int
 p2 = &j; // error, p2 is a constant pointer

so now if we replace pointer to reference we can see similar things, except reference by itself is not changeable ie you cannot make reference to refer to another object after it is created (unlike non constant pointer) and any reference is like constant pointer. So const reference in this meaning does not make any sense and usually by const reference people mean reference to a const type. That what quote from primer means.

As for difference in your code, yes there is difference - you cannot change object through const reference does not matter if that reference points to const object or not.

Slava
  • 43,454
  • 1
  • 47
  • 90
4

There's a useful way to figure out what constness means in pointers and references, which is to read the declaration from right to left (see these answers). So const int &r1 can be read as "r1 is a reference to an int const".

Basically, r1 refers to an int which cannot be modified. This means that the referred-to int is either a const int, or it's a simple int. The binding of a const const reference to a non-const object (for example, when writing something like int i = 5; const int& r = i;) is perfectly legal because there's nothing wrong with not modifying a non-const object.

alter_igel
  • 6,899
  • 3
  • 21
  • 40
  • "The promotion to const in the second case..." Do you mean the first case (aka const reference to non const object)? – Steve Cho Aug 31 '18 at 00:06
  • @SteveCho I was referring to my own wording, not to the original question. Forgive me, I have clarified. – alter_igel Aug 31 '18 at 00:19
1

I think this means that making a reference a "const" when it is referenced to a non const object does absolutely nothing. We may as well take that const keyword out when defining that reference.

Not true.

You may not modify the a non-const object through a const reference.
You may modify a non-const object through a non-const reference.

Unless an object is created in the read-only section of a program, it is open for modifiction without adverse consequences. However, when you use a const reference to a non-const object, you are asking the compiler to not let you modify the object through that particular reference. It does not mean that you will not modify object.

It's similar to function arguments. When a function uses a const reference argument type, the function is promising to you that it will not modify the object. It does not mean that the object is not modifiable at all.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • "When a function uses a non-const reference argument type, the function is promising to you that it will not modify the object." Do you mean "When a function uses a CONST reference..."? – Steve Cho Aug 31 '18 at 00:04
0

If we use const with variable then its value can not be change and when it is used with const reference then its reference can not be changed if we used it with object then whole data is used in object it can not be changed.

0

It's also worth to mention the behavior when you pass both to a function call fun1(const int& R1) vs. fun2(int & R1)

In fun1 you may call it with either cost or variable, for example fun1(5) or fun1(var1); assuming int var1=5;

In fun2, you simply can't call it with const, fun2(5) will give you compiler error, which means in that case you've to add another overloading implementation to cover this case. Bad design!

Embedeer
  • 53
  • 4