没用任何强制转换,也没重载操作符,为什么const失效了?该怎么处理

没用任何强制转换,也没重载操作符,为什么const失效了???
const   char   *p= "hello ";
cout < <&p < < "   " < <p < <endl;

p= "newstring ";
cout < <&p < < "   " < <p < <endl;
为什么p指向的字符串内容变了(地址并没有变)?
我看了《Effective   C++》条款21和条款29,但讲的都是通过重载操作符来改变p的内容的,好象没讲到这一点。请高人解释原因

------解决方案--------------------
这个const是说你不可以这样:
const char *p= "hello ";
p[0] = 'a '; //通过const指针修改该指针指向的数据
------解决方案--------------------
你的理解全部乱套。。。。

(1)“const char *p”这个是指向常量的指针,而不是个指针常量。
所谓“指向常量的指针”,并不是说它必须指向一个常量,而是指你不能修改它指向的内容。比如,对于这个p,如果你企图执行:
p[0] = 'A ';
*p = 'B ';
等类似修改所指内容的操作,编译将报错。

(2)p是个局部变量,只要它的作用域还有效,它就只有一个地址(当然也不是说离开作用域就可以有两个地址了,离开了作用域再讨论地址就没有任何意义了),它的地址怎么可能变化呢?啥时候见过一个变量的地址还能随着赋值而改变的?赋值只能改变一个变量的值,而不可能改变它的地址,指针变量是保存地址的,它的值就是它保存的那个地址,即通常所说的它指向的位置。

(3)正因为p只是一个指向常量的指针,而非一个指针常量,所以你虽然不能作“*p = 'A ';”这种改变它内容的动作,但是却完全可以对它重新赋值——不是改变它指向的内容,而是让它整个指向另外一个地方,即你的程序中的 "newstring "。当然,它还是它,虽然指向了新的地方,但它还是不能修改指向的内容;

(4)要想定义常量指针,应该这样:
char * const p = "hello ";
这一个正好反过来,你可以能过p把一个字母改成 'A ':
p[0] = 'A ';
于是原来的字符串也就变成了“Aello”,但你却不能让它指向别处,比如:
p = "string ";
是会出错的。

(5)要想定义指向常量的常量指针,就这样:
const char* const p = "hello ";
这一个常到家了,指向内容不能修改(即不能通过p修改 "hello "的任何一个字符),本身亦不能修改(即也不能再指向别处)。
------解决方案--------------------
const 修饰的是指针,
这个指针虽然被修饰为const ,其实他可以指向其他东西。
因此可以这样说 当const指向一个非常量类型时,这个修饰可以忽略。
而当他指向一个常量时,常量要求一个const类型指向他,这时候,const刚好发挥他的作用,满足了常量的要求。
C++primer里面有句话非常能帮助理解这个:const指针是一个自以为指向了const对象的指针