我正在阅读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的低级常量限定不相同。为什么最后一个问题是正确的?
答案 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 const
是int
永远不会改变的承诺。如果你试试这个:
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');
});
,它可以做很多简化假设来加速代码。