Reputation: 1326
Suppose to have the code
#include <iostream>
struct A{
int y;
int& x;
A():y(0),x(y){}
};
void f(int& x){
x++;
}
void g(const A& a){
f(a.x);
//f(a.y);
}
int main(){
A a;
g(a);
std::cout<<a.y<<std::endl;
}
inside g() calling f() on y is not allowed because a is passed with the const modifier however, the value of y can be modified inside g() by calling f on x;
With pointers, a similar things can be obtained very similarly
struct B{
int* x;
}
and
g(const B&){
*x++;
}
is allowed. This is perfectly clear: We have a const pointer to non-const int. But in the previous reference example, if references ARE the object, why do in this case they behave as pointers? What are the design policies under this behavior?
Upvotes: 3
Views: 208
Reputation: 67723
if references ARE the object
references are not objects though - they're references to objects.
You're right that making a reference itself const isn't very useful: since they're non-reseatable, they can't be mutated like pointers in any case.
In fact, it might be more helpful to think of a reference as a const pointer (not a pointer-to-const!) with special syntax.
Note that if you want an indirection which does propogate constness from the referee to the referent (ie, to prevent the f(a.x)
call here), you can write a smart pointer-style thing to do it.
Concrete example
struct A
{
int x;
int *p;
int &r;
A() : x(0), p(&x), r(x) {}
};
Now in A a
:
a.x
is a mutable inta.p
is a mutable pointer (so we can reseat it) to a mutable int (we can change the value of the integer it points to)a.r
is a reference to a mutable int
... but in const A b
:
b.x
is a constant integerb.p
is a constant pointer (so we can't reseat it) to a mutable intb.r
is a reference to a mutable int
Upvotes: 4
Reputation: 157334
The actual language in the standard is
8.3.2 References [dcl.ref]
1 - [...] [ Note: A reference can be thought of as a name of an object. —end note ]
So if a reference is a name of an object, not an object itself, then it makes sense that causing the enclosing structure to be const
makes the name const
(which is meaningless, as references can't be rebound), but not the object itself.
We also see
6 - If a typedef, a type template-parameter, or a decltype-specifier denotes a type TR that is a reference to a type T, an attempt to create the type “lvalue reference to cv TR” creates the type “lvalue reference to T” [...]
Since member access on a cv object creates a cv lvalue, the same applies and the cv qualification is extinguished.
Upvotes: 3
Reputation: 39354
In C++ references are usually implemented by pointers. (I think that the sizeof
a reference and pointer are the same).
Indeed I usually think of references as pointers, but with different syntax.
Upvotes: 0