//Example 1
const double pie = 3.14; // const object
const double *cptr = &pie; // pointer-to-const to const object
double *ptr = &pie; // ERROR - pointer-to-non-const to const
//Example 2
double pie = 3.14; // non-const object
const double *cptr = &pie; // pointer-to-const to non-const object
double *ptr = &pie; // pointer-to-non-const to non-const object
最初我虽然允许指向非常量对象的常量指针,因为它只是意味着 指向 const 的指针不会更改非常量对象。
但是我刚刚读过c++书 允许指向非常量对象的常量指针的原因是因为没有 指向 const 的指针真正知道它指向的对象是否是 const 的方法, 所以它将它指向的对象视为 const 但按照相同的逻辑,指向非 const 的指针会将 const 对象视为非 const 对象 但编译器会在编译时抛出错误。
我在这里遗漏了什么吗?
声明 const 表示:“该变量的值不应更改。”
声明指向 const 的指针表示:“我无意更改我指向的变量”。
问题1:为什么当一个指向变量的指针被赋值为const的地址时会出现错误?
// Example 1
const int i = 0;
int * p = &i; /* Error */
答案:因为第一行说“请保证
i
的值不会改变”,但是在第二行编译器就无法再做出这样的保证——指针上的类型信息p
不够严格,无法告诉编译器不允许更改指向的值i
。
问题2:当将指向const的指针赋值为变量的地址时,为什么不会出现错误?
// Example 2
int j = 0;
const int * q = &j; /* No error */
答案: 因为指向 const 的指针表示:“请保证
j
的值不会通过 q
改变 ”。注意 via q
很重要,因为指向 const 声明的指针并不意味着指向的值必须是常量,只是使用指针的人不能使用指针来更改值 .
指向常量的指针
const double *p
将其指向的对象视为常量对象,即它不允许您更改它。一旦取消引用指针
*p
你正在处理一个常量对象。如果您尝试修改它,
*p = 1.0;
您将从编译器中收到一条错误消息。
另一方面,指向非常量的指针,
double *p
将其指向的对象视为非常量,因此允许您修改其值:
*p = 1.0;
变得合法。然而,如果在任何给定时间你有一个恒定的对象
const double d = 1.0;
您将无法创建指向它的非常量指针:
double *p = &d;
不会被编译器接受。所以是的,编译器允许指向非常量的指针来修改它指向的对象。但它并不能让您创建一个指向常量对象的非常量指针。因此,您不会遇到可以使用指向非常量的指针来修改常量对象的情况。
关于标题中的问题:这主要是语言设计的决定。然而,编译器可以依赖某些对象永远不会改变值这一事实意味着可以进行各种优化。例如,如果同一个指针在两次取消引用之间的函数中被取消引用两次,并且该指针是指向 const 的指针,则编译器将假定它实际上不必从内存中获取该值两次,因为在第一次和第二次解除引用之间不允许该值发生变化。