2016-06-09 79 views
1

我正在阅读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低水平不变资格和我不一样。为什么最后一个staement正确?

+0

我不明白你的问题..你有什么困惑? – immibis

+1

您的问题的标题似乎与问题的内容无关。我没有看到任何关于复制对象的问题。 –

+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规则。基本上他们试图保持常量的正确性。像p = p3这样的任务当然不会做。

我认为你将有一个更容易理解的时间的规则,如果你为他们显然没有帮助您了解这里发生了什么掉落“顶级”和“低级别” const东西。

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指针。 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它可以做出很多简化的假设来加速代码。