Here is the explanation for the behaviour.

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.
Originally Posted by hbchen
(1)A non-const reference may be attached only to an object of the same type as the reference itself.
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.
Originally Posted by hbchen
(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.
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.
Originally Posted by hbchen
(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.
For any reference variable, its value can be changed by accessing that memory through some other pointer. Here is the test code.
int main()
	const int &a = 2;
	int *pa;

	pa = (int *)&a;
	*pa = 4;

	cout << a =  << a <<  *pa =  << *pa;
	cout << &a =  << &a <<  pa =  << pa;	
||| Dharma |||