The use of const in C + + is very extensive, different location to use the meaning is not the same, so want to write an article to make a summary.
First of all, it is clear that the const is the basic meaning of "unchanging", but the same does not mean that nothing is changed, as will be seen below.
1. Const and variable
Basic principle: Const Variable (object) cannot be modified
The introduction of const in a variable is related to the number of demons, the so-called "magic number" refers to a sudden occurrence of a constant value (also known as a literal constant).
for (int i = 0; i < i++)
{
//Todo
}
In the example above, 512 is the magic number, and 512 suddenly appears in the loop, which makes it impossible to know its meaning, so introduce a const.
const int length = A;
for (int i = 0; i < length; i++)
{
//Todo
}
This means that the loop is within the length range.
1.1 Const modifies a variable (or object) so that it becomes a constant, indicating that the value of the variable cannot be modified again, and that is why it must be initialized when defining a constant.
Scope of the 1.2 const constant:
We know that declaring a variable in a global scope (in particular, a variable that is not a const modifier) works for the entire program and can be referenced in other files because it declares a variable in the global scope and is extern-decorated by default.
Declaring a const variable in the global scope, which is not an extern decoration by default, is only intended for use in this file, and for access in other files, it needs to be explicitly declared as extern
2. Const and Reference
Basic principle: A const reference is a reference to a const variable (object)
const int ival = 1024;
const int &refval = ival;
2.1 Const Reference can point to a const variable of a related type (not of this type)
Double dval = 3.14;
const int &refval = Dval;
The compiler converts a double to a temporary int object, and then lets the const reference bind to the temporary object, so changing the value of the Dval does not change the refval, that is, Dval is still a non-const variable, and refval is still a constant reference.
Primer Fourth Edition is the above, but I in VS2012, the const can also point to a non-const variable of this type, the reason for finding the data is probably to meet the reference-campatible condition.
Theoretically, we should strictly observe that the constant reference points to the constant object, and the very reference points to the very object to avoid errors.
3. Const and pointers
The relationship between a const and a pointer is divided into two types: a const-decorated pointer and a pointer to a const object, where the const position is not the same
3.1 Pointer to const object (const is in front of pointer symbol *)
For a const object, you must point to it with a pointer to the const. The reason is that the Const modifier makes the object impossible to change, and if the pointer is not a pointer to const, the object can be modified by a pointer, which is not allowed.
const int ival = 1;
const int *ptrval = &ival;
Conversely, for a pointer to a const object, you can point to any object, how do you understand this? Let's look at the process of assigning pointers first:
Assigns Val's address to PTR because the assignment is only an address, so it is not known whether the object that PTR points to is const.
If we assign an address to a pointer to a const, then the pointer thinks it is a const object, that is, the PTR pointer points to an object that is "self-considered" a const.
int ival = 1;
const int *ptrval = &ival;
The above program is correct and we need to be clear that ival is a non const variable, so we can change the value of ival by assigning ival to the value. Ptrval points to an object that is considered const, so we cannot change the value of Ival by *ptrval.
3.2 Const-Decorated pointer (const is behind the pointer symbol *)
A pointer to a const type is declared, which means that the pointer itself is a constant and cannot be modified.
How to understand? The value of the pointer itself is an address, and if the pointer itself is a constant, the address value cannot be modified, which means that the pointer can only point to this address and cannot point to other places. The contents of the address that the pointer points to, however, do not belong to the value of the pointer itself, so the content that it points to can be changed.
int ival = 1;
int *const ptr = &ival;
*ptr = 2; OK
int ivaltwo = one;
PTR = &ivaltwo //Error
In summary, you can define a const pointer that points to a const object
const int *const ptr = &ival;
An error-prone const pointer in the 3.3 typedef
typedef string *PTR;
const PTR s_ptr;
The upper type cannot be directly replaced by a const string *s_prt; So that s_ptr is a pointer to a const string.
First, PTR is a pointer, and the const modifier is a pointer, so it should be string *const s_ptr; S_PTR is a const pointer that points to string.
4. Const and Array
The point of the const and array is that the const must initialize this principle when it is defined, so when using a dynamically allocated array, if the array stores a const-type object, it must be initialized (using the initialization symbol ()).
5. const and function return value
The return value of the modifier function to return a constant.
5.1 Returns passed by value
If the function returns with a value pass, such as returning an int, the function copies the returned value (for example, 47) to the external temporary storage unit (generating a temporary copy), so the addition of the Const modifier makes no sense
int foo ();
const int foo ();
The two are exactly the same. Note that the value pass produces a temporary copy, which is inefficient (the following const is spoken with the function arguments), so it is usually returned by reference passing.
5.2 Returns passed by reference (not much)
If the return value is not an intrinsic type, a reference pass is usually used to return the result, because the reference is passed by itself and no temporary copies need to be generated. However, it should be noted that only one alias is returned at this time.
ClassType &foo ();
Const ClassType &foo ();
A const-decorated return reference value that indicates that the result of a function call can only be assigned to a const reference of the same type.
5.3 Returns passing by pointer
Indicates that the function returns a pointer to a ClassType type, which points to a const object where the contents of the pointer cannot be modified, so the return value of the function can only be assigned to a pointer to the same type of Const.
Const ClassType *PTR = foo (); Ok
ClassType *ptr = foo (); Error
6. Const and Function parameters
First you need to be clear that the purpose of the Const modifier is to protect the modified content from being changed.
In C + +, function parameters are divided into value passing, pointer passing, and reference passing.
6.1 Value Transfer
The value pass produces a temporary copy of the function call, and the modification and operation of the incoming parameter in the function is the operation of the copy and does not change the value of the argument itself, so no const is required to protect it.
Value transfer protection is good, but the value of the delivery of the shortcomings, need to produce a temporary copy, if the incoming object, then the need for construction, replication, and destructor, such as the efficiency is not high. This is the time to consider reference passing
void foo1 (int x);
void Foo2 (ClassType instance); Large overhead
The following protection is meaningless:
void foo1 (const int x);
void Foo2 (const ClassType instance);
6.2 Reference Delivery
Lower the cost by passing in the reference to the argument. Because the reference is itself, there is no need to produce a temporary copy.
void foo1 (int &x);
void Foo2 (ClassType &ref);
For both functions, function calls and value passes are exactly the same, and the difference is that the X and ref obtained inside the function are the references that invoke the incoming arguments. Also because of this, a reference can change the argument by changing the arguments passed in by the function. This is dangerous for the argument, which requires the Const modifier to protect the incoming reference from being modified.
void foo1 (const int &x);
void Foo2 (const ClassType &ref);
Generally, for basic internal types, there is no such operation as object construction, so the following two kinds of protection parameters are not modified in the same way that the efficiency is basically the same.
void foo1 (int x);
void foo1 (const int &x);
6.3 Pointer Delivery
Pointer passing is the same as a reference pass when the protection parameter is not modified, and a function of pointer passing is to enlarge the range of receive parameters:
void foo1 (const ClassType *ptr);
Combining the above const with pointers, we know that PTR points to an object that is considered a const type, so! The object passed in is not necessarily a const-decorated object, it can be a const object, or it can be a non-const object. Conversely, if you do not have the parameters of the const modifier function, you can only pass in a non-const object.
It is necessary to be clear that, regardless of whether the const object is passed in, the object cannot be modified by the pointer, which is consistent with the relationship between the pointer and the const.
Finally, you need to know that const can only modify an input parameter, if it is an output parameter, whether it is a reference pass or a pointer pass, you cannot use the const modifier
7. Const with data members of the class
A const-decorated data member cannot be initialized in a constructor and can only be initialized with a member initialization list.
My understanding is that it is not permissible to initialize a data member in a constructor equivalent to two times the const value, because the data member is initialized using the member initialization list before the constructor executes.
The reason for this understanding is that you can refer to the initialization of reference types in a class, and you must initialize them in the initialization list, because reference types are also required to be initialized when they are defined, and are required to be the same as const, so both can only be initialized using the member initialization list.
8. Const and the member function of the class
In a const member function, the const is positioned after the function's argument list (the function declaration indicates that the function's return value is a constant)
A const-decorated member function indicates that a member function is a read-only function and does not change the member variable.
The true meaning of the const member function is that the const actually modifies the member function by the implied parameter this pointer, which means that the const ClassType *this is passed in, because this points to a const object and cannot be modified.
Because this is a pointer to an object, we need to combine the const with the knowledge of the pointer again:
(1) The const modifies this to get the const ClassType *this,this point to a "self-considered" object (that is, itself), so any object (either const or non-const) can invoke a const member function. Because the incoming pointer considers itself this object as a const object, it cannot be modified.
(2) For a const object, the default is to pass in the this pointer parameter when it calls a member function, because this points to a const object (itself), so the member function is the const modifier, and the member function is a const member function, so conversely, The const object can only invoke the const member function because it is not a const-decorated member function, the this pointer is not pointing to a const object.
(3) In the 8.2 's basically, further, each member function can invoke other member functions, each member function is passed into the this pointer, so the member function calls each other must keep the this pointer consistent, so the const member function can only call the const member function, because the two incoming this pointer is a const fix Decorated. For a non-const member function, it passes in the this pointer, which is not a const modifier, so it cannot be invoked.
Figuring out what the const really means is that it's important to keep the const member function passing in the sense of the const pointer, which needs to see whether the object (itself, the pointer, the reference) is a const.