My Note about the difference between const ref and non-const ref
(1)A non-const reference may be attached only to an object of the same type as the reference itself.
(2)A const reference may be bound to an object of a different type but the change of that object will not change the reference.
(3)A const reference can be bound to a variable of the same type, but you can not directly change the value of the const reference. However, any change of the variable will be reflected in the const reference.
Below is my test code and results:

Reference is nothing but exactly const pointer, ie, address of the variable cannot be changed, but the value can be. When a variable is declared as const reference, its value also becomes unchangable. Hence, ultimately const reference is nothing but const pointer to const.

By applying these rules, your observations can be easily understood.

hbchen said:

(1)A non-const reference may be attached only to an object of the same type as the reference itself.

Click to expand...

This is because, change in original must be reflected in the alias. This is not possible at run-time if alias and original are different types.

hbchen said:

(2)A const reference may be bound to an object of a different type but the change of that object will not change the reference.

Click to expand...

Since, const reference cannot be changed in future, initialized value is type casted and assigned. In this case, compliler is not creating alias. Instead, it is creating a new const variable. You can confirm this by printing the address of both.

hbchen said:

(3)A const reference can be bound to a variable of the same type, but you can not directly change the value of the const reference. However, any change of the variable will be reflected in the const reference.

Click to expand...

For any reference variable, its value can be changed by accessing that memory through some other pointer. Here is the test code.