10

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.

1
  • 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 Commented Aug 30, 2018 at 18:45

6 Answers 6

21

"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; 
Sign up to request clarification or add additional context in comments.

3 Comments

@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.
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?
@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 <vector>, 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.
10

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.

Comments

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.

2 Comments

"The promotion to const in the second case..." Do you mean the first case (aka const reference to non const object)?
@SteveCho I was referring to my own wording, not to the original question. Forgive me, I have clarified.
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.

1 Comment

"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..."?
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.

Comments

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!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.