复制对象时为什么忽略顶级常量?

时间:2016-06-09 04:32:24

标签: c++ const

我正在阅读C ++入门,我坚持这个主题。它是写的

int i=0;
const int ci=42; //const is top level.
const int *p2=&ci; //const is low level.
const int *const p3=p2; //rightmost const is top level,left one is low level. 
int *p=p3 //error.
p2=p3 //ok:p2 has the same low level constant qualification as p3.
int &r=ci; //error: can't bind an ordinary int to const int object
const int &r2=i; //ok:can bind const int to plain int.

现在如果在最后一个语句中忽略顶级常量,那么它应该给出错误,因为&r2和i的低级常量限定不相同。为什么最后一个问题是正确的?

2 个答案:

答案 0 :(得分:4)

你在一个问题中提出十亿个问题,但我总结一下。

  • 这些:

    int &r=ci; //error: can't bind an ordinary int to const int object
    const int &r2=i; //ok:can bind const int to plain int.
    

    遵循reference initialization的规则。左侧需要具有与右侧相同或更大的cv资格。

  • 这些:

    const int *p2=&ci; //const is low level.
    const int *const p3=p2; //rightmost const is top level,left one is low level. 
    int *p=p3 //error.
    p2=p3 //ok:p2 has the same low level constant qualification as p3.
    

    遵循qualification conversions的规则。基本上他们试图保持const的正确性。像p = p3这样的作业当然不会这样做。

如果你放弃了顶级"我认为你会更容易理解规则。和"低级" const这些东西,因为他们显然无法帮助您了解此处发生的事情。

答案 1 :(得分:0)

在处理const声明时,您会向后看。不幸的是,它有一个例外:const int因历史原因而被允许,但它与int const相同。

下面,const"回顾"到int所以p指向一个无法更改的int。

int const * p; 

在这里,const"回顾"到int *所以p不允许指向任何其他内容,但现在指向的内容可以通过p进行更改。

int i = 5; int j = 5;
int * const p = &i;
*p = 6;       // ok, you can still modify `i` through `p`
p = &j;       // error because you can't change what `p` points at

在这里,p是一个指向const int的const指针。 p不允许更改,并且指向的内容无法更改。

int i = 5; int j = 5
int const * const p = &i;
*p = 6;       // error, promised not to makes changes through `p`
p = &j;       // error `p` is stuck to `i`

当将一件事物分配给另一件事物时,规则是承诺不能被破坏。 int constint永远不会改变的承诺。如果你试试这个:

int const i = 5;
int * p = &i;      // error

并且编译器允许您这样做,然后您可以通过执行此操作来打破i永远不会改变的承诺

*p = 6;

现在i将从5更改为6,打破了i永远不会改变的承诺。

反之亦然,因为你没有违背任何承诺。在这种情况下,您只是承诺在通过指针i

访问p时不要更改int i = 5; int const * p = &i; *p = 6; // error, because we promised not to change `i` through `p` i = 6; // ok, because `i` itself is not const
const

const作为内置安全检查非常重要。如果您声明为const的内容发生更改,编译器将给出错误。您可以将类的方法声明为const,这是一种承诺,即该方法不会更改类中的任何数据。很容易忘记并稍后修改该方法以更改类中的某些内容,但编译器会提醒您。

对于优化也很重要。如果编译器知道某些东西是$('a').attr('href',function(i,oldhref) { return oldhref.replace( ".html",'.php'); }); ,它可以做很多简化假设来加速代码。