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?
It is valid code, because a
is not const
. A const
reference means you cannot modify the refered-to object via the reference.
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".
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With