Constant const allows us to draw a line between change and constant.
The initial motivation of the const design is to replace the pre-processor # define for value substitution. From then on, its application scope includes pointers, function variables, return types, class objects, and member functions.
Const Application 1: Value substitution:
Typical C language uses a pre-processor to replace values:
# Define bufsize 100;
Bufsize is a name that does not occupy storage space and can be placed in a header file. It aims to provide a value for all the compilation units that use it.
Features: when using C language for program design, the pre-processor can establish a macro without restrictions and use it to replace the value. because the pre-processor only performs text replacement, it does not have the idea of type check, nor does it have a tool for type check, it generates a foreshadowing for the confusion of the number of replicas.
The emergence of const is to make # define more secure.
Const in the header file
Like # define, the const must put the const in the header file. by including the header file, you can place the const definition in a separate place and allocate it to a compilation unit.
Const in C ++ is an internal connection by default. That is to say, const is visible only in the header file defined by const, and cannot be seen by other mutations during connection.
When defining a const constant, it must be assigned to it unless it is described as extern const bufsize.
Although the above extern forces the compiler to allocate storage space, the C ++ compiler usually does not allocate space for const. Instead, it stores this definition in its symbol table, when const is used, it performs constant folding in the compiler.
Of course, for a complex mechanism, the compiler needs to allocate storage. In this case, the compiler creates storage to prevent constant folding. This is why const must use V as an internal connection by default, that is, the connection is only in a special compilation unit. Otherwise, connection errors may occur because many const files are stored in multiple CPP files. If the Connection Program sees the same definition in multiple object files, it will "complain ". However, because const uses internal connections by default, the Connection Program vbuhui does not conflict with those definitions that span the compilation unit connection. For a large number of internal data types used, including constant expressions, the compiler will perform constant folding.
Const security:
The role of const is not limited to replacing # defines in constant expressions. If you initialize a variable with the value generated during running and know that it remains unchanged during the lifetime of the variable, it is a good practice to limit the variable with Const.
In fact, if you want to keep a value unchanged, you should make it a constant (const ). this not only provides security measures to prevent unexpected changes, but also eliminates storage and memory operations to make the code generated by the compiler more effective.
Set:
Const can use a set, but the compiler cannot place a set in its symbol table. Therefore, the memory must be allocated. In this case, const means that the memory cannot be changed. however, the value cannot be used during compilation because the compiler does not need to know the stored content during compilation.
Const Application 2:
Reference is the alias of a variable. An operation on a variable is an operation on the variable.
I: pointer
We can also make the pointer conost. when processing the const pointer, the compiler will still try to block the storage allocation and perform constant folding. however, in this case, these features seem to be rarely used. More importantly, the compiler will give a notification if programmers want to change the usage of such pointers in code in the future, this greatly increases security.
When a const with a pointer is used, there are two methods: Or const modifies the object to which the pointer is directed or the const modifier is stored in the address of the pointer itself.
1: pointer to const
Const int * X; // The element to which it points does not change
X is a pointer pointing to a const Int. Initialization is not required here, because X can point to anything, but it cannot be changed.
Int const * X;
X is a normal int pointer pointing to a const.
2: const pointer
To make the pointer itself a const pointer, you must put the part indicated by the const on the right side.
Int D;
Int * const x = & D; // the pointer itself remains unchanged
X is a pointer, which is a const pointer to an int.
Note: at any time, a pointer definition is stored in the same row, and each pointer is initialized in the defined place. it is because of this that "*" is assigned to the data type. in fact, "*" is a combination of identifiers.
II: function parameters and return values
If the object is passed by value, it makes no sense for the user to use Const. If the value of an object of the User-Defined type is returned as a constant, this means that the return value cannot be modified. If the address is transmitted or returned, const ensures that the address content is not changed.
A: Pass the const value
If the value is passed, you can use const to limit the function parameters. The parameter is passed as a value, so make a copy of the variable immediately (this Convention is hidden for the user ).
In a function, const has the following definition: The parameter cannot be changed. So it is actually a function creator tool, not a function caller tool.
Calling the const limitation parameter inside the function is better than using the const limitation parameter in the parameter table.
B: returns the const value.
Returning an internal data type does not require const modification, because the compiler will not make it a left value (because it is always a value rather than a variable ). Therefore, if you do not want to use the custom type as the left value, you must use Const.
All temporary variables are automatically constants.
C: Transfer and return addresses
To avoid modifying the initial value of a pointer (reference), use Const. In fact, whenever we use a pointer, we use const to modify it.
The compiler does not allow the address stored in the const pointer to create a non-const pointer.
D: standard value transfer
In C, the value transfer is common, but the pointer is required when the address is to be transferred.
When passing a parameter in C ++, the first thing that comes to mind is the transfer of reference and the transfer of reference through a constant (const. If it is passed through the constant const reference, this means that the function will not be able to change the content of this address, and the value is actually the same.
Due to the reference syntax, it is possible to pass a temporary variable to a function with a reference, however, a temporary object cannot be passed to a function with a pointer-because it must have a clear address, the following situation occurs: a temporary variable that is always a constant, the address can be passed to a function.
Example:
Class IV
A: The meaning of using const in a class is: this is a constant during the life cycle of this object. However, for this constant, different constants of a class can contain a different value.
When a const is created in a class, the initial value cannot be given. This initialization job must be initialized at the place where it is created. In the const topic of the constructor, const must have been initialized (because in the function, how does it initialize anywhere, in this way, the const value cannot be changed in different places of the constructor). Therefore, the const value must be initialized in the initialization list of the constructor. Its behavior occurs before any code of the constructor is executed.
Class Fred
{
Const size;
Public:
Fred ();
Fred (int I );
};
FRED: Fred (): size (100 ){}
FRED: Fred (int I): size (I ){}
B: constants during compilation
The const in the class indicates the lifetime of the specified object, rather than the const for this class .. If you want to ensure the constants in the class, and during the compilation period, the job needs to be Enum;
Class bunch
{
Enum {size = 100 ;}
Int I [size];
};
C: const object and member functions
Const objects and const member functions are inseparable. If you declare a member function as a const function, it means that the compiler can call this function for a const object. A member function without a special declaration of const is regarded as a function for modifying the data member in the object, and the compiler will not allow a const object to call this function.
Similar to inline, functions identified by const must be emphasized during definition.
//
# Include <iostream>
# Include <stdlib>
# Include <time>
Using namespace STD;
Class quoter
{
Int lasquote;
Public:
Quoter ();
Int lastquote () const;
Const char * Quote ();
};
Quoter: quoter ()
{
Lasquote =-1;
Time_t T;
Srand (unsigned) Time (& T); // seed Generator
}
Int quoter: lastquote () const
{
Return lasquote;
}
Const char * quoter: quote ()
{
Static const char * quotes [] = {
"Are we having fun yet? ",
"Doctors always know best ",
"Is it... automic"
};
Const qsize = sizeof quotes/sizeof * quotes;
Int qnum = rand () % qsize;
While (lasquote> = 0 & qnum = lasquote)
Qnum = rand () % qsize;
Return quotes [lasquote = qnum];
}
Int main ()
{
Quoter Q;
Const quoter CQ;
CQ. lastquote (); // OK
Q. lastquote ();
// CQ. Quote ();
For (INT I = 0; I <20; I ++)
Cout <q. Quote () <Endl;
Return 0;
}
By bit and by member const
If we want to create a const function, but still want to change some data in the object. In this way, we need to understand the difference between the two concepts by consthe and by member Const.
The bitwise const means that every bit in the object is fixed, so every bit of the object is never changed.
By member const, although the entire object is conceptually unchanged, a Member may change. When the compiler is told that an object is const, it will protect this object.
Class y
{
Int I, J;
Public:
Y () {I = J = 0 ;}
Void F () const;
};
Public void Y: F () const
{
// I ++; // Error
(Y *) This)-> J ++;
}
Void main ()
{
Const y YY;
YY. F ();
}
Another way is to use mutable to modify the variable to indicate that it can change its value in the const function.
Class y
{
Int I;
Mutable Int J;
Public:
Y () {I = J = 0 ;}
Void F () const;
};
Public void Y: F () const
{
// I ++; // Error
// (Y *) This)-> J ++;
J ++;
}
Void main ()
{
Const y YY;
YY. F ();
}
Note: The keyword const can define objects, function parameters, return values, and member functions as constants, and eliminate the replacement of pre-processing values without any impact on the Preprocessor. All of these provide a very good type check form and security for the program design. Using the so-called const correctness (using const wherever possible) has helped the project.