The const keyword in C + + is detailed

Source: Internet
Author: User

1. What is a const?

Const means a constant type, a const-modified variable or object cannot be modified and updated, and of course, in some cases, we can change it rescue.

2. Why should I introduce a const?

The original purpose was to replace the precompiled Directive: Define MAX (1024), obviously such a macro definition constant is inherited from the C language, C + + realizes that this macro substitution has a marginal effect, so I hope that the const can replace it

What is the role of 3.const?

(1) You can define const constants, which have immutability. For example:
const int max=100; int Array[max];

(2) Easy to type check, so that the compiler to deal with the content of more understanding, eliminate some hidden dangers. For example: void f (const int i) {...} The compiler will know that I is a constant, does not allow modification, and also reminds the programmer not to try to modify it

3) can avoid the ambiguity of the number appears, the same can be easily adjusted and modified parameters. As with the definition of a macro, you can do it without changing it. As in (1), if you want to modify the content of Max, only need: const int max=you want; To improve the reusability of the code, you only need to modify the value of the const variable.

(4) Can protect the modified things, prevent accidental modification, enhance the robustness of the program. Or the above example, if I is modified in the function body, the compiler will make an error, for example:
void f (const int i) {i=10;//error!}

(5) Provides a reference for function overloading: the normal function and the constant function are the overloaded
Class A {...
void f (int i) {...}//a function
void f (int i) const {...}//overload of previous function ...
};

(6) Can save space and avoid unnecessary memory allocation. For example:
#define PI 3.14159//Macro definition Constants
Const DOULBE pi=3.14159; Pi is not placed in ROM at this time ...
Double I=pi; Allocate memory for PI at this time, no longer assigned!
Double I=pi; Macro substitution during compilation, allocating memory
Double J=pi; No memory allocation, duplicate a copy
Double J=pi; Another macro replacement, another memory allocation!
Const definition constants from the assembly point of view, just give the corresponding memory address, instead of the immediate number as given in # define, so the const definition of the constant in the program runs only one copy, and the constant defined by the # # has several copies in memory.

(7) Improved efficiency. The compiler typically does not allocate storage space for ordinary const constants, but instead saves them in the symbol table, which makes it a constant during compilation, without the storage and read memory operations, making it highly efficient. In some cases, though, the value of the const constant that is read into memory is modified, but not in the symbol table, because the compiler ignores the behavior and still takes the original data in the symbol table as the standard.

4. How to use const?
(1) Modifier general constants general constants are constants that refer to simple types. When this constant is defined, the modifier const can be used in front of the type descriptor, or it can be used in the type description specifier. For example:
int const x=2; or const int x=2;

(2) The modifier constant group defines or describes a constant group that can be in the following format:
int const A[5]={1, 2, 3, 4, 5};
const int A[5]={1, 2, 3, 4, 5};

A constant group represents a piece of memory that is not modifiable.

(3) The constant object of a modified object refers to the object constants, which are defined in the following format:
Class A; const A;
a const A; When a constant object is defined, it is also initialized, and the object can no longer be updated (that is, modified), the modifier const can be placed after the class name, or placed in front of the class name.

(4) Modifier constant pointer
const int *a; The const modifier points to the object, a variable, the object that a points to is immutable, that is, the *a is not mutable
int const *A; The const modifier points to the object, a variable, the object that a points to is not mutable
int *const A; The const modifier pointer A, a is immutable, a points to an object that is variable, that is, *a variable
const int *CONST a;//Pointer A and a point object are not mutable

(5) A modifier reference using the Const modifier can also decorate a reference, the referenced reference is a constant reference, and the object referenced by the reference cannot be updated. The format is defined as follows:
Const Double & V;

(6) The constant-parameter const modifier of the modifier function can also modify the function's pass-through parameters in the following format:
void Fun (const int Var); Tells the compiler that the parameter Var cannot be changed in the function body, thus preventing some unintentional or erroneous modifications by the user. Also tell the programmer not to try to modify it

(7) The return value of the modifier function: The const modifier can also modify the return value of the function, which is the return value cannot be changed, in the following format:
const int FUN1 (); Const MyClass FUN2 ();

(8) A member function of a decorated class: the const modifier can also decorate a member function of a class, in the following format:
Class ClassName {
Public
int fun () const; ...//class of the constant member function, can not modify any data inside the class, read-only.
So that the data in the class cannot be modified when the function fun is called

(9) A const constant in an external file is referenced, meaning that the constant is defined in a different source file.
extern const int i;//the correct reference
extern const INT j=10;//Error! Constants cannot be re-assigned to another, note that constants must be initialized! For example: const int i=5;

5. Some points worthy of discussion:
(1) What does the const mean?
Having said so much, what do you think the const means? A modifier? Interface abstraction? A new type? Perhaps all, when Stroustup first introduced this keyword, it was only possible to put the object in Rom, and for a const object, C + + allowed both static initialization and dynamic initialization. The ideal const object should be writable before its constructor is complete, and can be written after the function execution begins, in other words, the const object has the invariant from the completion of the constructor to the execution of the function, and if this rule is violated, the result is undefined! Although we put the const in ROM, but this does not guarantee any form of const degenerate, we will give a concrete approach. Whether a const object is put into ROM or protected by a storage protection mechanism, it can only be guaranteed that the object has not changed for the user. In other words, the scrap collector (which we'll discuss in detail later) or the database system has no problem with a const modification.
(2) Bit const V.S. Abstract const?
There are several ways to interpret the keyword const, the most common being the bit const and the abstract const. Let's look at an example: class A {public: ... A f (const a& a); ...... }; If an abstract const is interpreted, it is that the F function does not alter the abstract value of the referenced object, and if the bit const is used to interpret it, then the F function does not alter any of the bits of the referenced object. We can see that the bit explanation is the C + + definition of the const problem, and the const member function is not allowed to modify any of the data members of the object it is in. Why is that? Because there are 2 benefits to using the bit const: The biggest benefit is that it is easy to detect the event that violates the bit const rule: The compiler only uses it to find out if there are any assignments to the data member. In addition, if we use bit const, then, for some simple const object, we can put it safely into the ROM, for some programs, this is a very important optimization method. (For the optimization process, we will be devoted to the discussion at the time) of course, bit Const also has shortcomings, otherwise, the abstract const does not produce the necessary. First, bit-const is less abstract than the abstract const level! In fact, as we all know, the lower the level of abstraction of a library interface, the more difficult it is to use this library. Second, the library interface using the bit const exposes some implementation details of the library, which often brings some negative effects. Therefore, in the Library interface and program implementation details, we should adopt the abstract const. Sometimes we might want to make some other explanation for the const, so it's important to note that at the moment most of the explanations for const are type insecure, and here we don't give an example, you can think for yourself, in short, we try to avoid the re-interpretation of Const.

(3) What are the limitations of constants placed inside a class?
Take a look at the following example:
Class A {
Private
const int c3 = 7; // ??? Error, a constant member can only be initialized as a member list.
static int c4 = 7; // ??? Error, static members must be initialized outside the class
static const float c5 = 7; // ??? ...... errors, static and const, are initialized outside the class member, as Static.
};
Do you think the 3 sentences above are right? Oh, all wrong! When using the initialization syntax inside this class, the constant must be an integer or enum 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 rule? In general, a class is declared in a header file, and the header file is included in a number of cells that call each other. However, to avoid complex compiler rules, C + + requires that each object have a single definition. If C + + allows an entity to be defined inside a class that occupies memory like an object, the rule is destroyed.

(4) How do I initialize a constant inside a class?
One method is to use static and const and initialize it internally, as in the example above, and another very common method is to initialize the list:
Class A {
Public
A (): I (2) {}
Private
const int i;
};

Another way is to initialize externally, for example:
Class A {
Public
A () {}
Private
The static const int i;//Note must be static!
};
const int a::i=3;

(5) Are there any special combinations of constants and arrays? Let's give the following code:
const int SIZE[3]={10,20,50};
int array[size[2]];
What's the problem? By the way, compile and pass! Why is it?
The const can be used for collections, but the compiler cannot store a collection in its symbol table, so memory must be allocated. In this case, const means "a piece of storage that cannot be changed." However, its value cannot be used at compile time because the compiler does not need to know what is stored at compile time. Naturally, as the size of the array is not:) You look at the following example:
Class A {
Public
A (int i=0): test[2] {}//} Do you think it's OK? Error
Private
const int TEST[2];
};

Class A {
Public
A (int i=0):
Private
The static const int test[2];//must be declared as static
};

const int a::test[2]={1,2};//is correct and is initialized outside the class
VC6 but why? On this question, some time ago, Njboy asked me what was the matter? I asked him, "What do you think?" "He thought about it, gave an explanation, and you can look at it: we know that the compiler heap initialization list is done within the constructor, and the order of initialization is based on the order of the data declaration before the available code is explicitly invoked. The initialization time should have no problem, then it is only the compiler to do what the array of hands and feet! Actually do what hands and feet, I do not know, I had to speculate on him: the compiler search to test found is a non-static array, so, for him to allocate memory space, it should be noted here, it should be allocated, not first allocated test[0], and then initialized with the initialization of the list, and then allocate test[ 1], this causes the initialization of the array to be actually assigned! However, constants are not allowed to be assigned, so they cannot be passed. Oh, look at this piece of sounding words, really let me laugh dead! Njboy don't blame me for exposing you short: My explanation for this is this: the C + + standard has a stipulation that unordered objects are not allowed to initialize inside a class, and arrays are obviously unordered, so this initialization is wrong! For him, it can only be initialized outside the class, and if you want it to pass, just declare it static and initialize it. Here we see that the combination of constants and arrays is nothing special! Everything is an array of woe!

(6) This pointer is not a const type?
This pointer is a very important concept, then how to understand her? Maybe the topic is too big, so let's narrow it down: what kind of a pointer is this? This depends on the situation: if the this pointer is only a class type in a non-const member function, if the this pointer is a const class type in the Const member function, if the this pointer is a volatile class type in the volatile member function.

(7) is const a reference object that is not overloaded?
First Look at the following example:
class A {
...
void f (int i) {...} A function
void f (int i) const {...} Overloads of the previous function
...
}; The above is overloaded is no problem, then the following?
class A {
...
void f (int i) {...} A function
void f (const int i) {...} ????? Error, the value is not overloaded, it is impossible to distinguish what action it has done
...
}; This is wrong, compile and pass. Does it mean that the const of internal parameters is not overloaded? Look at the following example:
class A {
...
void F (int&) {...} A function
void f (const int&) {...} ?????
...
}; This procedure is correct, it seems that the above conclusion is wrong. Why is that? This concerns the transparency of the interface. When passing by value, this is transparent to the user, and the user does not know what the function does to the formal parameter, in which case overloading is meaningless, so the rules cannot be overloaded! When a pointer or reference is introduced, the user will have a certain understanding of the operation of the function, is no longer transparent, the overload is meaningful, so the provisions can be overloaded.

(8) Under what circumstances is the const allocated memory?
Here's what I thought possible, of course, some compilers are optimized and may not allocate memory.
A, as a non-static class member;
B, when used for collection;
C, when the address is taken;
D, in the main function inside the body through the function to obtain the value;
E, the const class or struct has a user-defined constructor, destructor, or base class;.
F, when the length of the const is longer than the computer word size;
G, the const in the parameter;
H, when the extern is used. Do not know if there is any other situation, welcome expert pointing:)
(9) is the temporary variable a constant?
In many cases, the compiler must establish a temporary object. Like any other object, they require storage space and must be constructed and deleted. The difference is that we never see the compiler responsible for determining their fate and the details of their existence. For the draft C + + standard, the temporary object is automatically a constant. Because we do not normally have access to temporary objects, we cannot use the information associated with them, so it is possible to tell a temporary object to make some changes that might go wrong. Of course, this is related to the compiler, for example: VC6, VC7 have extended this, so, with the temporary object to do the Lvalue, the compiler did not error.

(10) Is there any problem with static collocation? Suppose you have a class:
Class A {
Public
......
static void F () const {...}
......
}; We find that the compiler will make an error, because in this case, static cannot coexist with the const! Why is it? Because static does not have this pointer, but const decorates the this pointer, so ...

(11) How to modify constants?
Sometimes we have to modify the data within the class, but our interface is declared const, what should we do with it? My views on this issue are as follows:
1) Standard usage: The mutable keyword can ignore the const attribute

Class A {
Public
A (int i=0): Test (i) {}
void SetValue (int i) const {test=i;}
private:mutable int test;//is handled here, variables modified with the mutable keyword can be unconstrained and can still be modified when encountering Const.
};

2) Forced conversion: const_cast

Class A {
Public
A (int i=0): Test (i) {}
void SetValue (int i) const {
Const_cast (test) =i;//uses the CAST keyword that is provided by C + + to remove the const attribute:const_cast<>
}
Private
int test;
};

3) Flexible pointers:
Int* class A {
Public
A (int i=0): Test (i) {}
void SetValue (int i) const {*test=i;}
Private
int* test; Here processing, test can not be modified, but *test can be modified, the advantages of pointers are shown
};

4) Undefined processing
Class A {
Public
A (int i=0): Test (i) {}
void SetValue (int i) const {
int *p= (int*) &test; *p=i;//here deal with the skill of playing with pointers
}
Private
int test;
Note that although this can be modified, the result is undefined, avoid using!

5) Internal processing: this pointer
Class A {
Public
A (int i=0): Test (i) {}
void SetValue (int i) const {
((A *) this)->test=i;//deal here! , which is handled by this pointer, is actually a trick to play with pointers.
}
Private
int test;
};

6) The most alternative processing: spatial layout, is to consider the problem from the memory distribution angle
Class A {
Public
A (int i=0): Test (i), C (' a ') {}
Private
char c;
const int test;
};
int main ()
{
A (3);
A * pa=&a;//takes to the first address of the class
char* p= (char*) pa;//cast pointer
int* pi= (int*) (p+4);//offset to the starting position of the memory of the const int test variable,
*pi=5;//changed the value of test here! Although the value of the const int test in memory is modified, it does not necessarily take effect in the symbol table.
return 0;
}
Although I gave the 6 method, but I just want to explain how to change, but in addition to the first usage (this is officially recommended), and another 5 usage, we do not advocate, do not because I wrote this, you use it, otherwise, I really want to fraught
(12) Finally, let's discuss the dynamic creation of a constant object. Since the compiler can dynamically initialize constants, it is natural to create them dynamically, for example:
Const int* pi=new const INT (10); Here are 2 points to note:
1) Const object must be initialized! So (10) is not to be less.
2) The pointer returned by new must be of type Const. So can we create an array dynamically? The answer is no, because an array of new built-in types cannot be initialized. Here we ignore the array is the class type, also for the class internal array initialization We also made such a neglect, because this involves the problem of arrays, we will discuss later.

The above content is reproduced to the Cattle People blog: http://blog.sina.com.cn/s/blog_4d6e44860100b4xo.html

The const keyword in C + + is detailed

Related Article

Contact Us

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.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.