为什么在复制对象时忽略顶级常量
Why are top level Constants ignored while copying objects?
我正在阅读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的低级常量限定不相同。为什么最后一次停留是正确的??
你在一个问题中提出了10亿个问题,但我会总结一下。
-
这些:
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.
遵循引用初始化的规则。左侧需要具有与右侧相同或更大的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.
遵循资格转换规则。本质上,他们试图保持常量的正确性。像
p = p3
这样的任务肯定做不到。
我认为,如果你放弃"顶级"answers"低级"const
的东西,你会更容易理解规则,因为它们显然无助于你理解这里发生的事情。
在处理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
是指向常量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
永远不会改变的承诺。
反过来也没关系,因为你没有违背任何承诺。在这种情况下,您只是承诺当您通过指针p
访问i
时不会更改它
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
,它可以进行大量简化假设以加快代码的速度。
- 为什么C++在将一个对象复制到另一个对象时需要对这两个对象进行低级常量限定
- 犰狳C++ - 从常量内存初始化只读矩阵而不复制
- 通过从构造函数中的'this'复制的指针改变常量对象
- 为什么编译器在使用"无常量复制构造函数"时抱怨?
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- 给定一个右值,为什么移动ctor比常量复制ctor更匹配
- C++自动生成的具有常量和非常量引用的复制构造函数
- 为什么一对常量是微不足道的可复制的,而对不是?
- 将值从指针复制到常量对象参数
- 委派复制构造函数和常量数据初始化
- 函数指针,可以采用具有常量引用或复制参数的函数
- C++复制按引用返回和按常量引用值返回
- 如何在忽略 null 的同时将数据从 char [] 复制到常量字符 *
- 为什么 GCC 拒绝复制赋值操作中的常量引用
- 将常量引用转换为智能指针而不复制
- 将字符串复制到类中的常量字符
- 你能为具有常量成员的联合编写一个复制构造函数吗?
- 移动构造函数和非常量复制构造函数
- 如何允许临时性的非常量复制构造函数
- 为什么在c++ 11中将std::pair类标准更改为不允许只有非常量复制构造函数的类型?