C ++ improvements Const in-depth improvement [Repost]

xiaoxiao2021-03-06  97

We may learn about the use of Const, but it is not necessarily mastered for the meticulous technical details of Const. Const's usage is simply introduced in many textbooks, where we are detailed and analyzed in congenization. Const is adopted by C , and is added to standard C, but their meaning is completely different. In C, in the old version (before), if you want to create a constant, you must use the preprocessor: #define pi 3.14159

Thereafter, in any case, it will be replaced with 3.14159 by the preprocessor. The compiler does not check the PI, that is, it can be used alternative to the value of unrestricted, if it is inadvertent, it is likely to be incorrectly introduced by the pre-processing, which is often difficult to find.

We don't get the address of the PI (ie, the pointer and reference cannot be transmitted to the PI). C introduces the concept of naming constants, name constants are like variables, but its value cannot be changed. If you try to change a const object, the compiler will generate an error. Const and normal variables have a scope, so constings inside the function will not affect the rest of the program. In C , consT can replace the pre-processor #define for value, and const has a safe type, so you don't have to worry about introducing errors like a preparation.

In the usual case, Const is just the symbol table that is assigned to the compiler (the symbol table is only compiled, the compiler is in the compiler in the compiler. The value defined in the value is a simple replacement), and the value is replaced when used, and does not create a storage space for Const. We put the Const's definition in the header, so by containing the header file, we can put the constance separately in one place and assign it to a compilation unit, and Const is an internal connection (internal connection means only to be compiled). File Create a storage space, other files can use the same marker and global variables, the compiler does not find a conflict, the external connection means creates a separate storage space for all compiled files, general global variables and function names The external connection is expressed through the extern declaration, which can be accessed by other files) that is, constant can only be accessed by files it defined. When defining a const, a value must be assigned, unless to explain with Extern:

EXTERN Const Int A;

This means that Const's definition is in other parts, this is just a statement, but such a practice makes Const use an external connection, that is, the above Extern enforcement is allocated to the storage of Const, so we can't use it. Const as a constant folding (in the case of possible case, the value of the symbol constant replaces the change of the changed name, this alternative process is used as a constant folding), even if we define the value of Const elsewhere, such as:

EXTERN Const Int A = 3;

Since the value of Const is placed in a storage unit, the compiler does not delay the contents of the storage unit during the compiled process. If we do this:

INT B [A];

The compiler will give us an error message.

It is impossible to allocate storage space because of a complex structure, such as a collection, compiler is not complex to save the collection to its symbol table, so you must allocate memory space, which means "this is A piece of storage that cannot be changed ", of course, it cannot use its value during compilation, because the compiler does not know the content:

Const Int i [] = {1, 2, 3, 4};

// float f [i [2]]; // will get an error message, the compiler prompt cannot find a constant expression in the array definition. Because the compiler relies and reads data by moving stack pointers. Therefore, since the Constance definition must be an internal connection because it cannot be avoided, the definition of Const must be internal connection, otherwise it will cause an error because many constings are allocated in multiple files. Let's take a simple and effective code to illustrate the constant folds of Const:

#include const Int A = 3; const INT b = a 1; float * f = (float *) & b; char C [B 3]; void main () {const char gc = cin. Get (); const char C2 = GC 3;}

We can see that A is a Const, b is calculated from A, because A is a constant expression, and it is also a Const, which is also a compiler. Then the following pointer f obtained the address of B, so it forces the compiler to assign a storage space to b, but even if the storage space is allocated, since the compiler already knows the value of B, it still does not hinder the large hours of determining the array C. b.

In the main function main (), the value of the identifier GC is not known during the compilation, which means that the storage space is required, but initialization should be done in the definition point, and once initialized, the value cannot be changed, we discove C2 It is calculated by GC, which is the same as the scope of other type constings, which is an improvement to the #define usage.

When C introduces constants, standard C has also introduced constations, but the meaning of Const in C is very different in C , and Const in C is "a common variable that cannot be changed", and Const constants is always The allocated storage space and its name is a global value, ready-to-use external connection. So in C:

Const int size = 100; char C [size];

I have a mistake. But you can write this in C:

CONST INT size

So this is reasonable because the const in C is default as an external connection. Using qualifiers Const in C language is not very useful, if you want to use a named value in a constant expression (must be evaluated during compilation), you must use the pre-processor #define.

In C , you can make the pointer a const, which is useful. If you want to change the use of Const this pointer in the program code, the compiler will give notifications, which greatly improves security. When using a pointer with Const, we have two options: the object of Const Demoding pointers, or the storage space you point on your own point yourself.

If you want to make a change pointing, you need to write:

const INT * P;

Here P is a pointer pointing to const int, it doesn't need to be initialized, because P can point to any identifier, it is not a const, but it does not change, the same, we can write this:

INT const * p;

These two methods are equivalent, depending on the personal habits and the coding style, the programmer should decide which one to use. If you want the pointer to be a constant, you must put the part indicated by * on the right.

INT A = 3; int * const j = & a

The compiler requires an initial value, which is constant during the life of the pointer, that is, the pointer always points to the address of A, but it is possible to change the value in its address: * J = 4;

It can also be a const pointer to a const object:

Const Int * J1 = & A; INT Const * J2 = & A;

This pointer and object cannot be changed, and both forms are equally equivalent. At the time of assignment, we need to assign a non-Const's address to a const pointer, but you cannot assign a const object address to a non-Const pointer because it may change the value of the object by assigning pointers. Of course, it can also be assigned by the type of forced conversion, but do this break the security provided by Const.

Const is also used to limit the return value of the function parameters and functions. If the function parameter is passed, that is, the initial value indicating the variable is not changed, if the return value of the function is constant, for internal types Whether it is a cosnt is irrelevant, the compiler does not let it become a left value, because it is a value rather than a variable, so using const is excess, for example::

CONST INT f () {Return 1;} void main () {int a = f ();}

However, when processing the user-defined type, it is very meaningful to return constants in value. At this time, the return value of the function cannot be directly assigned and cannot be modified. It is only used as a left value as a left value, but this is often lost because the function return value is usually saved as a temporary amount, and the compiler will be temporarily cleared. The results lost all modifications. You can pass or return an address with const (ie, a pointer or a reference):

Const Int * const func (const INT * p) {static int a = * p; return & a;

The data in the parameter pointer P pointing cannot be changed, and the value of the P will be assigned to the static variable A, then returns A, which is a static variable, after the function runs, its lifetime No end, so it can return its address. Because the function returns a const Int * type, the return value of the function FUNC cannot be assigned a pointer that is non-pointing const *, but it also accepts a const Int * const and a const INT * pointer because the function is generated when the function returns A Const temporary pointer is used to store A's address, so that this raw variable cannot be changed, so that the CONST on the right is only when it is used as the left value.

Const is also used in classes, but its meaning is different, we can create Const's data members, members of Const, even constant objects, but keep the objects of the CONST complicated, so the const object can only Call the Const member function.

Const's data distribution is allocated in each object of the class, and once the value is initialized to be a constant in the life of the object, the initialization work must be initialized in the constructor when establishing a constant member in the class. If we want to create a constant member during compilation, you need to use the Static qualifier in front of the constant member, so all objects have only one instance:

Class x {static const Int size = 50; int A [size]; public: x ();

The Const object can only call the Const member function, and a normal object can also call the Const member function, so the Const member function is more general, but the member function will not default to const. Declare a constant function, you need to put the const qualifier behind the function name: Void f (void) const;

When we use the Const member function, encountering the need to change the data member, you can use mutable to specify special specified:

Class x {mutable int I; public: x (); void noChange () const;

Void x :: nochange const () {i ;}

Const eliminates the adverse effects of the value of the preprocessor, and provides good types of check forms and security, which is helpful to our programming in the possible places. - Nanwand

转载请注明原文地址:https://www.9cbs.com/read-123608.html

New Post(0)