2.4 const qualifiers

2.4 const qualifiers

The keyword const adds a limit to the type of the variable

const int bufSize = 12;

The object modified by const cannot change its value once it is created, so the object modified by it must be initialized.
Compared with non-const type objects, objects modified by const can perform most of the operations of non-const objects, but cannot be modified or reassigned.

By default, const objects are only available in files

When a const-modified variable is initialized at compile time, the compiler will change all places where the variable is used into the corresponding value during compilation.
insert image description here
("C++ Primer")

2.4.1 Reference constants

A reference constant cannot modify the object it is bound to, and a non-const reference cannot point to a constant object

int i = 10;
const int &r = i;
r = 11; // 错误:表达式必须是可修改的左值
const int i  = 10;
int &r = i; //错误:将 "int &" 类型的引用绑定到 "const int" 类型的初始值设定项时,限定符被丢弃

initialization and reference to const

The type of the reference must be consistent with the type of the referenced object. Exception: Any
expression is allowed to be used as the initial value when initializing a constant reference, as long as the result of the expression can be converted to the reference type.

int i = 10;
const int &r = i; // 允许常量引用绑定到一个普通int对象上
const int &r1 = 45; // 正确:r1是一个常量引用
const int &r2 = r*2; // 正确:r2是一个常量引用
int &r3 = r1*2; // 错误:r3是一个普通的非常常量引用

A reference to const may refer to an object that is not const

A constant reference only limits the operations that the reference can participate in, and does not limit whether the referenced object itself is a constant. Since an object may also be a non-const, other means of changing the value of a constant reference are allowed.

int i = 10;
const int &r = i;
i = 15;
cout << r << endl; // 15
int &r1 = i;
r1 = 16;
cout << r << endl; // 16

2.4.2 const and pointers

Pointers can point to constants or non-constants. To store the address of a constant object, the pointer must be modified by the const keyword. A pointer to a constant cannot be used to change the value of the object it points to.

const double i = 3.14; // 常量对象
const double *p = &i; // 正确:p是指向常量的指针
*p = 12; // 错误:指向常量的指针不能用于改变其指向的对象的值
double *p1 = &i; //错误:"const double *" 类型的值不能用于初始化 "double *" 类型的实体

The type of a pointer to a constant must be the same as the type of the pointed object, exception:
a pointer to a constant points to a non-constant object

int i = 10;
const int *p = &i; // 正确:常量指针指向了非常量对象
 i = 15; // 可以通过修改非常量对象的值来修改指向常量的指针
 cout<< *p << endl; // 15

const pointer

Pointers are objects and references are not, so just like other types of objects, it is allowed to position the pointer itself as a constant. The constant pointer (const pointer) must be initialized. Once the initialization is completed, the value of the pointer (the stored address) cannot be changed.

const int i = 10;
const int *const pip = &i; // pip是一个指向常量的常量指针

	int i = 15;
    int *const p = &i;
    cout << *p << endl;//15
    *p = 45;
    cout << *p << endl;//45
    i = 10;
    cout << *p <<endl;//10
    int k = 33;
    p = &k; // 错误:常量指针所存放的地址不可以被改变

The pointer to the constant object must be a pointer modified by const. The pointer to the constant can store the address of the non-constant object or the constant object, and the address stored by the const pointer is fixed.

2.4.3 Top-level const

The pointer itself is an object. Whether the pointer itself is a constant and whether the object pointed to by the pointer is a constant are two independent issues. In order to distinguish these two terms, use the top-level const and the bottom-level const to distinguish.

type top-level const underlying const
explain pointers are constant objects pointer to a constant object
example int *const p = &i; int const i = 10;const int *p =&i;

Expand the definition of top-level const and bottom-level const: top-level const refers to any constant object, while bottom-level const is related to the basic types of composite types such as pointers and references.

int i = 10;
int *const p1 = &i;// 不可以修改p1的值,这是一个顶层const
const int *p2 = &i; // 可以修改p2的值,这是一个底层const
const int ci = 12;// 不可以修改ci的值,这是一个顶层const

When performing copy operations, there is a clear distinction between top-level const and bottom-level const. The top-level const is not affected, because the object modified by the top-level const is a constant object and cannot be modified. Performing a copy operation will not change the value of the copied object, so whether the object copied in or copied out is a constant does not matter.

 int i = 11;
    const int ci = 10;

    const int *p1 = &ci; // p1:底层cosnt
    const int *const p2 = p2; // 第一个const是底层const,第二个是顶层const
    i= ci; // 正确:拷贝ci的值,ci是一个顶层const对此操作无影响
    p1 = p2; // 正确:p2和p3指向的对象类型相同,p3顶层const的部分不影响

For underlying const, objects copied in and copied out must have the same underlying qualification

const int ci = 10;
const int *p2 = &i; 
int *p = p2; // 错误:p2是底层const,而p无底层const资格

2.4.4 constexpr and constant expressions

A constant expression is an expression whose value does not change and whose result can be obtained during compilation. Literal values ​​are constant expressions, and const objects initialized with constant expressions are also constant expressions. Whether an object or expression is a constant expression is determined by its data type and initial value.

const int  i = 10;// i是常量表达式
const int  l = i +1; // l是常量表达式
int s = 2;// s不是常量表达式,其数据类型只是一个普通的int
const int  k = get_size();// k不是常量表达式,因为常量k的初始值是要运行函数之后才能够获取到

constexpr variable

The new C++11 standard stipulates that variables are allowed to be declared as constexpr types so that the compiler can verify whether the value of the variable is a constant expression. A variable declared as cosntexpr must be a constant and must be initialized with a constant expression.

constexpr int i = 20; // 20是常量表达式
constexpr int l = size(); // 当size函数是一个cosntexpr函数时才是一条正确的语句

constexpr variable

The type used when declaring constexpr becomes a "literal value type". Arithmetic types, reference types, and pointers all belong to literal value types, and custom classes, IO libraries, and string types do not belong to literal value types.
The initial value of a constexpr pointer must be nullptr or 0, or an object stored at a fixed address.
Variables in the function body are generally not stored in fixed addresses, so constexpr pointers cannot point to such variables, and the fixed addresses of objects defined in all function bodies can be used to initialize constexpr.

constexpr and pointers

If a pointer is defined in a constexpr declaration, the qualifier constexpr is only valid for the pointer and has nothing to do with the object pointed to by the pointer

const int *p = nullptr; // p是一个指向整型常量的指针
constexpr int *q = nullptr; //q是一个指向整数的常量指针

constexpr sets the defined object q to the top level.

Guess you like

Origin blog.csdn.net/weixin_44848852/article/details/123977764