1. What is const? A common type is a type described by the Type modifier Const. The values of variables or objects 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, the void F (const int I) {......} 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, if you want to modify the content of Max in (1), you only need to: const int max = new value!
(4) It can protect modified things, prevent accidental modifications, and enhance program robustness. 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; // at this time, the PI is not put into the Rom ......
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 point of view, only the corresponding memory address is given, rather than the number of immediate values as # define. Therefore, the const-defined constants have only one copy during the program running, while the # define-defined constants have several copies in the memory.
(7) improved efficiency. Generally, the compiler does not allocate storage space for common const constants, but stores them in the symbol table, which makes it a constant during compilation without the operation of storage and read memory, this makes it highly efficient.
4. How to Use const? (1) modify a constant. A common constant is a constant of a simple type. When defining such constants, the modifier const can be used before or after the type specifier. For example:
Int const x = 2; or const int x = 2;
(2) modify the definition of a regular array 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) modifying 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 be placed after the class name or 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) The const modifier can also be used to describe the regular reference. The referenced object cannot be updated because the referenced object is often referenced. The definition format is as follows:
Const double & V;
(6) The const modifier of the modifier can also modify the Transfer Parameters of the 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 users' unintentional or incorrect modifications.
(7) modifier return value: the const modifier can also modify the return value of the function. The return value cannot be changed. The format is as follows:
Const int fun1 ();
Const myclass fun2 ();
(8) modifier class member functions: the const modifier can also modify the class member functions 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! A constant cannot be assigned another value. In addition, it must be noted that the constant must be initialized! Example: const int I = 5;
5. 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 only made a possibility to put the object into Rom. For a const object, C ++ allows static initialization, it can also be dynamically initialized. The ideal const object should be writable before its const function is completed, and can be written after the function execution starts. In other words, const objects have immutability from constructor completion to function execution. If this rule is violated, the results are undefined! Although we put const into Rom, this does not guarantee any form of const degradation. We will give a specific solution later. Whether the const object is put into the ROM or protected by the storage protection mechanism, it can only be ensured that the object has not changed for the user. In other words, the waste collector (which we will discuss in detail later) or the database system's modifications to a const have no problem.
(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 A {public:... f (const A & );......};
If the abstract const is used for interpretation, the F function will not change the abstract value of the referenced object. If the bitwise const is used for interpretation, then the f function will not change any bitwise element of the referenced object. We can see that the bitwise Element Interpretation is exactly the definition of const in C ++. The const member function is not allowed to modify any data member of its object. Why? Because bitwise const has two advantages: the biggest advantage is that it can easily detect events that violate the rules of the bitwise const: the compiler only needs to find out whether to assign values to data members. In addition, if we use bitwise const, we can safely put some simple const objects into Rom. For some programs, this is undoubtedly an important optimization method. (We will discuss optimization processing in a specific way.) 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 a library interface, the more difficult it is to use this library. Second, the database interface using bitwise const exposes some implementation details of the database, which often brings some negative effects. Therefore, we should use abstract const in terms of library interfaces and program implementation details. Sometimes, we may want to make some other explanations for const, so we should note that at present, most of the explanations for const are type insecure. Here we will not give an example, you can think about 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, the 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, classes are declared in a header file, and header files are contained in many mutually called units. However, to avoid complicated compiler rules, C ++ requires that each object has only one unique definition. If C ++ Allows defining an object that occupies the same memory as an object in the class, this rule will be destroyed.
(4) How to initialize constants inside the class?
One method is static and const, Which is 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? The following code is provided:
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 memory must be allocated. In this case, const means "a block of storage that cannot be changed ". However, the value cannot be used during compilation because the compiler does not need to know the stored content during compilation. Naturally, the size of the array will not work. You can 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? About this question, njboy asked me how it was going some time ago? I asked him, "What do you think ?" He thought about it and gave an explanation. Let's take a look: we know that the operations on the compiler heap initialization list are within the constructor, before explicitly calling available code, the initialization order is based on the data Declaration Order. There should be no problem with the initialization time, so only the compiler has done something to the array! In fact, I don't know what to do, so I had to guess him: the compiler searched for test and found it was a non-static array, So I allocated him memory space, it should be noted that the allocation is complete, instead of assigning test [0] first, and then using the initialization list to initialize and reassign test [1]. as a result, array Initialization is actually a value! However, constants do not allow assignment, so they cannot pass. Haha, I am so happy to see this story! Njboy: The C ++ standard stipulates that unordered objects cannot be initialized within the class, the array is obviously unordered, so such initialization is incorrect! It can only be initialized outside the class. If you want it to pass through, you only need to declare it as static and then initialize it. 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, so let's narrow down: What type is this pointer? This depends on the specific situation: in a non-const member function, the this pointer is only of the class type; In a const member function, the this pointer is of the const class type; 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) {...} // overload of the previous function
......
};
This is incorrect, but it cannot be compiled. Does it mean that the const of the internal parameter is not reloaded? Let's look at the following example:
Class {
......
Void F (Int &) {...} // a function
Void F (const Int &) {......} // overload of the previous function
......
};
This program is correct. It seems that the above conclusion is incorrect. Why? This involves interface transparency. When passing by value, this is transparent to users. users do not know what the function has done to the form parameter. In this case, it is meaningless to perform the overload, so it is required not to reload it! When a pointer or reference is introduced, the user will have a certain understanding of the function operations, and it is no longer transparent. In this case, overloading is meaningful, so it is required to be reloaded.
(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 require a bucket and must be constructed and deleted. The difference is that we never see the compiler deciding on their leaving and their details. For the draft C ++ standard: Temporary objects automatically become constants. Because we usually do not have access to temporary objects and cannot use relevant information, it is possible to tell the temporary objects to make some changes. Of course, this is related to the compiler. For example, vc6 and vc7 are all extended. Therefore, the compiler does not report an error when using a temporary object as the left value.
(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? Because static does not have this pointer, but const modifies this pointer, so...
(11) how to modify constants?
Sometimes we have to modify the data in the class, but our interface has been declared Const. What should we 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; // here!
};
2) forced conversion:
Const_cast Class {
Public:
A (INT I = 0): Test (I ){}
Void setvalue (int I) const {
Const_cast (TEST) = I;
} // Process it here!
PRIVATE:
Int test;
};
3) Flexible pointers:
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 the other five methods. Don't write this because I did, this is how you use it. 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 the class type of arrays, and we also ignore the class internal array initialization, because this involves the array issue, we will discuss it later.
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.