1. What is const?
A common type is a type described by the Type modifier Const. a variable or object Value of a common type cannot be updated.
. (Of course, we can steal the bar for updating :)
2. Why is const introduced?
The initial purpose of const is to replace precompiled commands, eliminate its shortcomings, and inherit its advantages.
.
3. What are the main functions of cons?
(1) const constants can be defined and are non-mutable.
For example:
Const int max = 100;
Int array [Max];
(2) It is easy to perform type check, so that the compiler can learn more about the processing content and eliminate some hidden risks.
For example:
Void F (const int I ){.........}
The compiler will know that I is a constant and cannot be modified;
(3) it can avoid the appearance of numbers with fuzzy meanings and easily adjust and modify parameters.
Same as macro definition, it can be changed as long as it remains unchanged! For example, in (1), if you want to modify
You only need to: const int max = you want!
(4) It can protect modified items, prevent accidental modification, and enhanceProgramRobustness.
In the above example, if I is modified in the function body, the compiler reports an error;
For example:
Void F (const int I) {I = 10; // error! }
(5) provides a reference for function overloading.
Class
{
......
Void F (int I) {...} // a function
Void F (int I) const {...} // overload of the previous function
......
};
(6) It can save space and avoid unnecessary memory allocation.
For example:
# Define PI 3.14159 // constant macro
Const doulbe Pi = 3.14159; // pi is not put into ROM at this time
......
Double I = PI; // at this time, the PI is allocated with memory and will not be allocated later!
Double I = PI; // macro replacement during compilation and Memory Allocation
Double J = PI; // no memory allocation
Double J = PI; // macro replacement, memory allocation again!
Const defines constants. From the Assembly perspective, it only gives the corresponding memory address, rather than # def
The constant defined by const has only one copy while the program is running.
The constants defined by efine have several copies in the memory.
(7) improved efficiency.
The compiler usually saves them in the symbol table instead of allocating storage space for common const constants,
This makes it a constant during compilation, without the storage and read memory operations, making it highly efficient.
3. How to Use const?
(1) Modifying General Constants
A constant is a constant of a simple type. When defining such constants, the modifier const can be used in the type description.
It can also be used after the type specifier.
For example:
Int const x = 2; or const int x = 2;
(2) Modifying regular Arrays
Define or describe a regular array in the following format:
Int const A [5] = {1, 2, 3, 4, 5 };
Const int A [5] = {1, 2, 3, 4, 5 };
(3) modify a constant object
A constant object is an object constant. The definition format is as follows:
Class;
Const;
A const;
When defining a common object, Initialization is also required, and the object cannot be updated. The modifier const can
After the class name, you can also put it before the class name.
(4) modify the constant pointer
Const int * A; // The object indicated by const. A is variable, and A is variable.
Int const * A; // const modifies the object to which a points. A is variable, and A is variable.
Int * const A; // const modifier pointer A, A is immutable, and a points to the object is variable
Const int * const A; // The objects pointed to by pointers A and A are not changeable.
(5) Modify common references
The const modifier can also be used to describe the reference. The referenced reference is a common reference.
Objects cannot be updated. The definition format is as follows:
Const double & V;
(6) modifying the common parameters of a function
The const modifier can also modify the passing parameters of a function. The format is as follows:
Void fun (const int var );
Tells the compiler that VaR cannot be changed in the function body, thus preventing unintentional or incorrect
Modify.
(7) modifier return value:
The const modifier can also modify the return value of a function, which cannot be changed. The format is as follows:
Const int fun1 ();
Const myclass fun2 ();
(8) modify the member functions of the class:
The const modifier can also modify the member functions of the class in the following format:
Class classname
{
Public:
Int fun () const;
.....
};
In this way, the data in the class cannot be modified when the function fun is called.
(9) reference the const constant in another connection file
Extern const int I; // correct reference
Extern const Int J = 10; // error! Constants cannot be assigned another value.
Note that constants must be initialized!
For example:
Const int I = 5;
4. Some points worth discussing:
(1) What does const mean?
So much, what do you think const means? A modifier? Interface abstraction? A new type?
Maybe all. When stroustup first introduced this keyword, it just made
Possible: For a const object, C ++ allows both static initialization and dynamic initialization. Management
The const object should be writable before its const function is completed.
In other words, const objects have immutability from constructor completion to function execution. If the const object violates
The results of this rule are undefined! Although we put the const into the Rom, this does not guarantee
What is the form of degradation, we will give a specific way later. Whether the const object is put into the ROM or stored
The protection mechanism can only ensure that the object is not changed for the user. In other words, waste collection
(We will discuss it in detail later. This is a reference) or how the database system makes modifications to a const.
Question.
(2) bitwise const v. S. Abstract const?
There are several methods to explain the keyword Const. The most common is bitwise const and abstract Const.
Here is an example:
Class
{
Public:
......
A f (const A & );
......
};
If the abstract const is used for explanation, the F function will not change the abstract value of the referenced object, as shown in
If the bitwise const is used for explanation, the F function will not change any bitwise element of the referenced object.
We can see that bitwise interpretation is exactly the definition of const in C ++, and const member functions are not allowed to be repaired.
Modify any data member of the object.
Why? Because bitwise const has two advantages:
The biggest benefit is that it is easy to detect events that violate the bitwise const rules: the compiler only needs to find
Find out whether to assign values to data members. In addition, if we use a bitwise const
For a relatively simple const object, we can safely put it into the Rom. For some programs, this is undoubtedly
An important optimization method. (For optimization processing, we will discuss it later)
Of course, bitwise const also has shortcomings. Otherwise, abstract const is unnecessary.
First, bitwise const is more abstract than abstract Const! As we all know
The lower the Abstraction Level of database interfaces, the more difficult it is to use this database.
Second, the database interface using bitwise const exposes some implementation details of the database, which often brings about some
Negative effects. Therefore, we should use abstract const in terms of library interfaces and program implementation details.
Sometimes, we may want to give some other explanations to const, so pay attention to it. Currently,
Most of the interpretations of const are type insecure. Here we will not give an example. You can consider it yourself,
In short, we try to avoid re-interpreting Const.
(3) What are the restrictions on constants placed inside the class?
Let's take a look at the example below:
Class
{
PRIVATE:
Const int C3 = 7 ;//???
Static int C4 = 7 ;//???
Static const float C5 = 7 ;//???
......
};
Do you think the above three sentences are correct? No! When using the internal initialization syntax of this type,
A constant must be an integer or enumeration type initialized by a constant expression, and must be in the form of static and Const.
This is obviously a very serious limitation!
So why does our Standards Committee make such a provision? Generally, a class is in a header file.
Is declared, and the header file is included in many units that call each other. However, to avoid complicated compiler rules,
C ++ requires that each object has only one separate definition. If C ++ allows a class to be defined as an object
Memory entity, this rule is destroyed.
(4) How to initialize constants inside the class?
One method is static and const, which are initialized internally, as shown in the preceding example;
Another common method is to initialize the list:
Class
{
Public:
A (INT I = 0): Test (I ){}
PRIVATE:
Const int I;
};
Another method is external initialization, for example:
Class
{
Public:
A (){}
PRIVATE:
Static const int I; // note that it must be static!
};
Const int A: I = 3;
(5) Is there any special combination of constants and arrays?
We provide the followingCode:
Const int size [3] = {10, 20, 50 };
Int array [size [2];
Is there any problem? By the way, compilation and translation fail! Why?
Const can be used for collections, but the compiler cannot store a set in its symbol table, so it must
Memory must be allocated. In this case, const means "a block of storage that cannot be changed ". However, its value is
Cannot be used because the compiler does not need to know the stored content during compilation. Naturally, the size of an array is not enough.
:)
Let's take a look at the following example:
Class
{
Public:
A (INT I = 0): Test [2] ({1, 2}) {}// do you think this is OK?
PRIVATE:
Const int test [2];
};
Vc6 is not available for further compilation. Why?
Two days ago, njboy asked me what was going on? I asked him, "What do you think ?" He
After thinking about it, let's give an explanation. You can see that we know that the compiler heap initialization list is being constructed.
Before the available code is explicitly called within the function, the initialization order is based on the data Declaration Order. The initialization time should be
There is no problem, so only the compiler has done something to the array! I don't know what to do.
I had to guess him: the compiler searched for test and found that it was a non-static array, so it allocated
Storage space. Note that it should be done after the allocation, instead of assigning test [0] first, and then using the initialization Column
Initialize the table and assign test [1]. As a result, array Initialization is actually a value! However, constants cannot be assigned values.
.
Haha, I am so happy to see this story! Njboy don't blame me for exposing you short Ah :) I am right
This is explained in the following way: the C ++ standard does not allow unordered objects to be initialized within the class. The array is obviously
Unordered, so such initialization is incorrect! Initialization can only be performed outside the class. If you want
It passes, and only needs to be declared as static and then initialized.
Here we can see that the combination of constants and arrays is nothing special! Everything is an array!
(6) is this pointer of the const type?
This pointer is a very important concept. How can we understand her? Maybe this topic is too big.
To narrow down: What type is this pointer? This depends on the specific situation: If in a non-const member function, T
The his pointer is only of the class type. In the const member function, this pointer is of the const class type. For example:
As a result, in the volatile member function, the this pointer is of the volatile class type.
(7) is const an overloaded reference object?
First, let's look at the following example in the pipeline:
Class
{
......
Void F (int I) {...} // a function
Void F (int I) const {...} // overload of the previous function
......
};
There is no problem with the above heavy load. What about the following?
Class
{
......
Void F (int I) {...} // a function
Void F (const int I ){......}//?????
......
};
This is incorrect, but it cannot be compiled. Does it mean that the const of the internal parameter is not reloaded? Again
See the following example:
Class
{
......
Void F (Int &) {...} // a function
Void F (const Int &){......}//?????
......
};
This program is correct. It seems that the above conclusion is incorrect. Why? This involves
Port transparency. When passing by value, this is transparent to the user, and the user does not know what the function has done to the form parameter.
In this case, it is meaningless to carry out the heavy load, so the heavy load is not required! When a pointer or reference is introduced
The user will have a certain understanding of function operations, and it is no longer transparent. In this case, the overload is meaningful.
It can be reloaded as specified.
(8) under what circumstances will the const allocate memory?
The following are possible situations that I think of. Of course, some compilers have been optimized and may not allocate memory.
A. As a non-static class member;
B. Used for collection;
C. When the address is obtained;
D. When the main function body obtains the value through the function;
E. When a const class or struct has a user-defined constructor, destructor, or base class ;.
F. When the const length is longer than the computer word length;
G. Const In the parameter;
H. When extern is used.
I don't know if there are any other situations. Thank you for your advice :)
(9) is the temporary variable a constant?
In many cases, the compiler must create a temporary object. Like any other object, they need to be stored empty
And must be constructed and deleted. The difference is that we never see the compiler deciding on their retention and their storage.
In the details. For the draft C ++ standard: Temporary objects automatically become constants. Because we usually do not have temporary access
Object, so it is possible to tell the temporary object to make some changes. Of course, this
It is related to the compiler. For example, both vc6 and vc7 are extended. Therefore, the compiler does not use a temporary object as the left value.
An error is reported. When they encounter a stream library, it will also lead to a series of problems, limited by space limitations, we are discussing temporary
Image.
(10) Is there a problem with static?
Assume there is a class:
Class
{
Public:
......
Static void F () const {......}
......
};
The compiler reports an error because static cannot coexist with const in this case!
Why is this problem? We know that the static function is used to make it be derived from various objects.
But const makes it impossible to modify the internal data of all objects that reference it. In other words, c
The meaning of onst is extended when the base class is unknown. to prevent this kind of thing from happening, just define stat.
IC cannot coexist with const (only in the above cases )!
Let's further think about what will happen if we don't define it like this? (In other words
Is this extension abnormal ?)
Because static functions can only call static objects and functions, and cannot coexist with virtual
L is dynamic, while static is static, and the internal mechanisms of the two are in conflict), so it is impossible to cause problems due to the virtual mechanism.
Let's look at another situation:
Class
{
Public:
Static void F () {cout <"A" <Endl ;}
Static void g () {f ();}
};
Class B: public
{
Public:
Static void F () {cout <"B" <Endl ;}
};
Because static functions are independent of external classes, B can also call G ().
So it is doomed that F () called by G () can only be Class A and will never be B! (Here, there are two F
() Does not conflict, because the compiler uses the name mangling mechanism.
Unexpected!
In that case, static cannot coexist with Const? Or there is no
But is this provision made by the Standards Committee for future expansion to avoid accidents? Hope you can give me some advice :)
(11) how to modify constants?
Sometimes we have to modify the data in the class, but our interface is declared cons
T, what should I do? My views on this issue are as follows:
1) standard usage: mutable
Class
{
Public:
A (INT I = 0): Test (I ){}
Void setvalue (int I) const {test = I ;}
PRIVATE:
Mutable int test; // process it here!
};
2) forced conversion: static_cast
Class
{
Public:
A (INT I = 0): Test (I ){}
Void setvalue (int I) const
{Static_cast <int> (TEST) = I;} // process it here!
PRIVATE:
Int test;
};
3) Flexible pointer: int *
Class
{
Public:
A (INT I = 0): Test (I ){}
Void setvalue (int I) const
{* Test = I ;}
PRIVATE:
Int * test; // process it here!
};
4) undefined Processing
Class
{
Public:
A (INT I = 0): Test (I ){}
Void setvalue (int I) const
{Int * P = (int *) & test; * P = I;} // process it here!
PRIVATE:
Int test;
};
Note: although the modification can be done here, the result is undefined and cannot be used!
5) internal processing: This pointer
Class
{
Public:
A (INT I = 0): Test (I ){}
Void setvalue (int I) const
{(A *) This)-> test = I;} // process it here!
PRIVATE:
Int test;
};
6) The most alternative solution: Spatial Layout
Class
{
Public:
A (INT I = 0): Test (I), C ('A '){}
PRIVATE:
Char C;
Const int test;
};
Int main ()
{
A A (3 );
A * pA = &;
Char * P = (char *) Pa;
Int * Pi = (int *) (p + 4); // Use edge Adjustment
* Pi = 5; // The value of test is changed here!
Return 0;
}
Although I have provided the method in step 6, I just want to explain how to change it. However, in addition to the first method
We do not advocate five other usage types. Do not use them because I have written them. Otherwise, I will miss you.
:)
(12) Finally, let's discuss the dynamic creation of constant objects.
Since the compiler can dynamically initialize constants, it can naturally be dynamically created, for example:
Const int * Pi = new const int (10 );
Note the following two points:
1) The const object must be initialized! Therefore, (10) cannot be minimized.
2) the pointer returned by new must be of the const type.
Can we dynamically create an array?
The answer is no, because the new built-in array cannot be initialized.
Here we ignore that arrays are of the class type, and we also made this for the class internal array initialization.
We will discuss this issue later.
Okay, let's write it here. It's too tired. Take a rest :)
5. Suggestions on using const
1. Be bold in using const, which will bring endless benefits to you, provided that you understand the original committee;
2. Avoid the most common assignment operation errors. For example, assign values to the const variable. For details, see the question.
3. Use a reference or pointer to use const in parameters, rather than general object instances, the reasons are the same as above;
4 the three usage of const in member functions (parameters, return values, and functions) should be well used;
5. Do not set the type of the return value of the function to const.
6. Do not set the return value type to reference the const of an object except the overload operator.