Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

in C++: Is const reference means "read-only view of" or it requires immutability of object being referenced?

Tags:

c++

The question can be formulated by example as following: is this snippet of code valid?

int a = 1;
const int& ca = a;
++a; //< Q: Is this valid?
cout << "a: " << a << endl;
cout << "ca: " << ca << endl; // Q: Is it guaranteed to output "2"? Is it valid at all?

With MSVC and MinGW the snippet above works as expected: if I query ca afterwords, it returns 2 (i.e. it was changed by non-const reference). But the question is: how this situation considered from the point of view of standard? Is it OK, that we change object, to which we have const reference (or e.g. we must define ca to be const volatile reference for the snippet to be correct)?

So, if snippet above is correct, then it means, that const reference does not guarantee, that referenced object is constant. It only prohibits us to change it via the given reference, i.e. establishes "read-only" view of referenced object. Is this correct?

Edit:
Thanks for everyone who answered my question. The answers state the thing, which seems natural for me. However I would really appreciate is someone give reference to specific clause in the c++ standard.

Edit2:
Original example was extended to make idea of the question more clear.

Edit3
Another example, which originally appeared in my comment to the answer of Mats Peterson.

class MyClass {
public:
    // ...
    const X& getX() const;
    void modifyX();
private:
    X m_x;
};

void someFun() {
    //...
    MyClass myObj = ... // non-cons
    const X& x = myObj.getX();
    // ...
    myObj.modifyX(); // Q: is `x` guaranteed to track value of x stored in myObj here?
}

And the question is: Is it allowed to compiler during optimization to remove updates of x variable, as it is declared const? E.g. if type X is bool, then storing x by value provides better performance and less memory consumption than storage by reference.

Putting it in another words: is it guaranteed, that local variable x will track changes of corresponding internal value inside myObj if subsequent calls to methods of myObj modify that internal value?

like image 816
Dmitrii Semikin Avatar asked Mar 16 '14 12:03

Dmitrii Semikin


3 Answers

It is valid code, because a is not const. A const reference means you cannot modify the refered-to object via the reference.

like image 86
juanchopanza Avatar answered Nov 01 '22 16:11

juanchopanza


In this particular case, all you are doing is creating a REFERENCE that is const - meaning that ca can't modify the value it refers to (a in this case).

A common usage is to pass a const reference to a function:

void foo(const int& cr)
{
   ... use cr ... 
}

This indicates that although the value is a reference, the function foo does not alter the value in cr. It is perfectly valid to call this function with a modifiable int variable, or even something that can't be referenced (for example foo(4); - the value 4 is just a constant, so can't really be used as a reference - the compiler will "fix" this by creating a temporary int variable, and pass the reference to that).

Of course, this is more commonly used with more complex types than int - for example std::string or std::vector. The main reason in this case is to avoid the value being copied, rather than "I want a reference".

like image 36
Mats Petersson Avatar answered Nov 01 '22 16:11

Mats Petersson


As a reference is just another name to a variable and not the object itself, yes in the snippet you show it can be thought as a read-only reference. The code provided with the reference can only access it but it does not guarantee that the object itself won't be changed in another place of your program.

like image 24
teh internets is made of catz Avatar answered Nov 01 '22 16:11

teh internets is made of catz