指向const的指针可以指向非const对象 - 语言设计还是技术原因?

kyp*_*ite 5 c++ pointers const



    //Example 1
    const double pie = 3.14;   //const object
    const double *cptr = &pie; //pointer-to-const to const object
    double *ptr = &pie;        //ERROR - non-pointer-to-const to const object

    //Example 2
    double pie = 3.14;         //non-const object
    const double *cptr = &pie; //non-pointer-to-const to non-const object
    double *ptr = &pie;        //non-pointer-to-const to non-const object


最初我虽然允许指向非const对象的指针,因为它只是意味着指向const的指针不会改变非const对象.

但我只是在c ++书中读到,指向const到非const对象的原因是允许的,因为指针到const指针无法真正知道它指向的对象是否为const,所以它对待对象它指向const但是通过相同的逻辑,非指针指向const会将const对象视为非const对象,但编译器将在编译时抛出错误.

我在这里错过了什么吗?

Bri*_*n L 5

声明const时说:“此变量的值不应更改。”

声明一个指向const的指针时,“我无意更改我要指向的变量”。


问题1:为什么在为变量的指针分配const地址时出现错误?

// Example 1
const int i = 0;
int * p = &i;        /* Error */
Run Code Online (Sandbox Code Playgroud)

答案:因为第一行说“请保证的值i不变”,但是在第二行中,编译器不能再做出保证-指针上的类型信息p不够严格,无法告诉编译器不要允许更改指向的值i


问题2:在为const的指针分配变量的地址时,为什么不出现错误?

// Example 2
int j = 0;
const int * q = &j;  /* No error */
Run Code Online (Sandbox Code Playgroud)

答:因为指向const的指针说,“请确保的值j不会通过q更改”。请注意,过q很重要,因为指向const声明的指针并不意味着指向的值必须是常量,只有使用指针的人才能使用指针更改值


jog*_*pan 3

指向 const 的指针

const double *p
Run Code Online (Sandbox Code Playgroud)

将它指向的对象视为常量对象,即它不允许您更改它。一旦取消对指针的引用

*p
Run Code Online (Sandbox Code Playgroud)

你正在处理一个常量对象。如果你尝试修改它,

*p = 1.0;
Run Code Online (Sandbox Code Playgroud)

您将从编译器中收到一条错误消息。

另一方面,指向非常量的指针

double *p
Run Code Online (Sandbox Code Playgroud)

将其指向的对象视为非常量,因此允许您修改其值:

*p = 1.0;
Run Code Online (Sandbox Code Playgroud)

变得合法。但是,如果在任何给定时间你有一个常量对象

const double d = 1.0;
Run Code Online (Sandbox Code Playgroud)

您将无法创建指向它的非常量指针:

double *p = &d;
Run Code Online (Sandbox Code Playgroud)

不会被编译器接受。所以是的,编译器允许指向非常量的指针来修改它指向的对象。但它不允许您创建指向常量对象的非常量指针。因此,您不会遇到可以使用指向非常量的指针来修改常量对象的情况。

关于标题中的问题:这主要是语言设计的决定。然而,编译器可以依赖某些对象永远不会改变值这一事实意味着可以进行各种优化。例如,如果同一个指针在两次取消引用之间的函数中被取消引用两次,并且该指针是指向 const 的指针,则编译器将假定它实际上不必从内存中获取该值两次,因为在第一次和第二次取消引用之间不允许该值发生变化。