Top-level const vs. bottom-level const

Recently, I watched C++ primer and encountered the concept of top-level const and bottom-level const. I haven't touched it before, and it's a bit confusing.


There will be a detailed introduction to the top-level const and the bottom-level const in the book and on the Internet, but reading translation books and some introductions on the Internet have made me dizzy. Let me first introduce some of my own understanding, which may not be correct, and then based on the book
. Summarize the introduction on the Internet and on the Internet.


My own understanding:
The so-called top-level const means that the variable remains unchanged after being modified by const, such as
const int a = 40; // the value of a will not change 
int *const ptr1 = &a; // ptr1 always points to a
and can also be
int b = a;
int *const ptr2 = &b; // ptr2 always points to b, but at this time the value of b can change the


so-called underlying const, which is generally a modified pointer object. After modification, the pointer must point to the corresponding constant, that is, point to the constant pointer, such as
const int a = 40;
const int *p1 = &a; // correct


int b = 50;
const int *p2 = &b; // wrong, because b is a non-constant




summary:


1. Top-level const and bottom-level const The concept
pointer itself is an object, because the pointer actually corresponds to a storage space of the memory unit, however, what the pointer points to is also a data object, therefore, the pointer is a constant
and the pointer points to a constant are two completely different the concept of,
The top-level const means that the pointer itself is a constant, and the bottom-level const means that the object pointed to by the pointer is a constant.
More generally, the top-level const can mean that any object is a constant. The data types are all established,
and the underlying const is related to the basic types of composite types such as pointers and references.
What is more special is that pointers can be both top-level const and bottom-level const, which is obviously different from other types.


2. Differences between top-level const and bottom-level const when performing copy operations
For top-level const and bottom-level const, there are obvious differences when performing object copying:


(1) Top-level const is not affected
int i = 0;  
const int ci = 42 ; // cannot change the value of ci, it is a top-level const  
i = ci; // correct: ci is a top-level const, has no effect on this operation  
const int *p2 = &ci; // allows to change the value of p2, this is A bottom-level const  
const int *const p3 = p2; // The const on the right is the top-level const, and the one on the left is the bottom-level const  
p2 = p3; // Correct: the objects pointed to by p2 and p3 are of the same type, and p3 is part of the top-level const Does not affect  (2) The restriction of the underlying cons cannot be ignored. It is required that the copied-out and copied-in objects have the same underlying const qualification or can be converted to the same data type. Generally, non-constants can be converted to constants, and vice versa.
 




int *p = p3; // wrong: p3 includes underlying const definition, and p has no  
underlying const p2 = p3; // correct: both p2 and p3 are underlying const  
p2 = &i; // correct: int* can be converted to const int*  
int &r = ci; // Error: ordinary int& cannot be bound to an int constant  
const int &r2 = i; // Correct: const int& can be bound to an ordinary int  


Let analyze the above code:
int *p = p3;
p3 is both a top-level const and a bottom-level const. When the object is copied, the top-level const part has no effect and need not be considered at all, but p3 is also a bottom-level const, which requires the copied object to have the same bottom-level const
qualification , but p does not, so it is wrong;


p2 = p3;
p3 requires the copied object to have the same underlying const qualification, p2 is also a underlying const, so it is correct;


p2 = &i;
taking the address of i will get int*, p2 It is const int*, the former is a non-constant, the latter is a constant, the type on the right side of the equal sign of the assignment statement is converted to the left, and the non-constant can be converted to a constant, so it is correct; int &r = ci; we know from the left


part
, What needs to be obtained is a reference bound to ci, and the type of the reference bound to ci is const int&, the type on the left side of the equal sign is int&, and the type on the right side of the equal sign in the assignment statement is converted to the left,
但是常量不能向非常量转换,所以是错误的;


const int &r2 = i;
由左侧部分我们知道,需要得到的是一个绑定到 i 上的引用,而绑定到 i 上的引用的类型是 int&,等号左侧的类型是 const int&,赋值语句等号右侧的类型向左侧转换,
一般非常量可以向非常量转换,所以是正确的。


不仅要注意类型转换的限制同时需要考虑const的性质

Guess you like

Origin blog.csdn.net/xiayulengleng/article/details/53576155