Mutable Keyword: mutable is an uncommon keyword in C ++, it can only be used for non-static and non-static data members of the class. We know that the status of an object is determined by the non-static data members of the object. As the data members change, the status of the object also changes! If a member function of a class is declared as a const type, this function will not change the object state, that is, the function will not modify non-static data members of the class. however, in some cases, you need to assign values to the data members of the class in this type of function. in this case, the mutable keyword is used. For example, [cpp] class Demo {public: Demo (){}~ Demo () {} public: bool getFlag () const {m_nAccess ++; return m_bFlag;} private: int m_nAccess; bool m_bFlag;}; int main () {return 0 ;} compile the code above to see the error C2166: l-value specifies const object. This indicates that the non-static data member of the class is changed in the const type function. in this case, you need to use mutable to modify the non-static data member m_nAccess In the const member function. The Code is as follows: [cpp] class Demo {public: Demo (){}~ Demo () {} public: bool getFlag () const {m_nAccess ++; return m_bFlag;} private: mutable int m_nAccess; bool m_bFlag;}; int main () {return 0;} in this way, no error will occur during re-compilation! The volatile keyword volatile is a little-known keyword in c/c ++. This keyword tells the compiler not to hold a temporary copy of a variable. It can be applied to basic types such as int, char, long ...... it is also applicable to the structure of C and the class of C ++. When the structure or Class Object is modified using volatile, all the members of the structure or class are considered volatile. using volatile does not deny the need for synchronization objects such as CRITICAL_SECTION, Mutex, and Event, for example, [cpp] int I; I = I + 3. In any case, there will always be a short period of time, I will be placed in a register, because arithmetic operations can only be performed in registers. In general, the volatitle keyword applies to rows rather than rows. Let's first implement a simple function to observe the deficiencies in the compilation code generated by the compiler, and to observe how the volatile keyword fixes the deficiency. There is a busy loop in this function (the so-called busy loop is also called busy waits, it is a high-waste CPU time cycle method) [cpp] void getKey (char * pch) {while (* pch = 0);} after you close all the optimization options in the VC development environment, compile the program and obtain the following results (assembly code) [cpp]; while (* pch = 0) $ L27; Load the address stored in pch mov eax, dword ptr _ pch $ [ebp]; Load the character into the EAX register movsx eax, byte ptr [eax]; Compare the value to zero test eax, eax; If not zero, exit loop jne $ L28; Jmp $ L27 $ L28;} This section of unoptimized code constantly loads the appropriate address, loads the content in the address, and test the result. The efficiency is quite low, but the results are very accurate. Now let's take a look at the compilation code generated by re-compiling the program after all the compiler's optimization option switches are turned on, compared with the above Code, what is the difference [cpp]; {; Load the address stored in pch mov eax, dword ptr _ pch $ [esp-4]; load the character into the AL register movsx al, byte ptr [eax]; while (* pch = 0); Compare the value in the AL register to zero test al, al; if still zero, try again je SHORT $ L84;} can be seen from the code length, which is much shorter than that without optimization. Note that the compiler places the MOV command out of the loop. This is a very good Optimization in a single thread. However, in a multi-threaded application, if another thread changes the variable value, the loop will never end. The tested value is always placed in the register. Therefore, this section of code has a huge BUG in the case of multithreading. The solution is to re-write the getKey function and declare the pch parameter as volatile. The Code is as follows: [cpp] void getKey (volatile char * pch) {while (* pch = 0);} This modification has no effect on the non-optimal version. The following figure shows the optimized result: [cpp] {; load the address stored in pch mov eax, dword ptr _ pch $ [esp-4]; while (* pch = 0) $ L84 :; directly compare the value to zero cmp byte ptr [eax], 0; If still zero, try again je SHORT $ L84;} the Modification result is perfect and the address will not change, so the address Declaration is moved out of the loop. The address content is volatile, so it is constantly re-checked in each loop. It is legal to pass a const volatile variable as a parameter to the function. Such a declaration means that the function cannot change the value of the variable, but the value of the variable can be changed by another thread at any time. The explicit keyword is rarely used when writing an application. Its function is to "Disable single-parameter constructor" for automatic type conversion, A typical example is the container type. In this type of constructor, you can pass the initial length as a parameter to the constructor. for example, you can declare a constructor [cpp] class Array {public: explicit Array (int size) ;}; here the explicit keyword plays a crucial role, without this keyword, this constructor can convert int to Array. once this happens, you can give the Array tribe an integer without causing any problems, such as: [cpp] Array arr (40); // correct Array arr = 40; // take a look at the following two operations for an error: [cpp] X x; Y y (x); // explicitly convert another [cpp] X x; Y y = x; // There is a small difference between implicit type conversion. The first method is explicit type conversion, and a new object of Type Y is generated based on Type x; the second method generates a new object of Type Y through implicit conversion. the application of the explicit keyword is mainly the constructor definition mentioned above. refer to the application of this keyword to see the STL source code, this keyword _ based is widely used. This keyword is mainly used to solve problems related to shared memory. It allows the pointer to be defined as a 32-bit offset value starting from a certain point, for example, [cpp] typedef struct tagDEMOSTRUCT {int a; char sz [10];} DEMOSTRUCT, * PDEMOSTRUCT; HANDLE hFileMapping = CreateFileMapping (); LPVOID lpShare = (LPDWORD) MapViewOfFile (); DEMOSTRUCT _ based (lpShare) * lpDemo; the above example declares a pointer lpDemo, which internally stores the offset value starting from lpShare, that is, the lpHead is the Offset Value Based on lpShare. the DEMOSTRUCT in the preceding example is just a structure defined randomly to represent any structure. although the _ based pointer is very easy to use, you must pay a certain cost for efficiency. every time you use the _ based pointer to process data, the CPU must add a base address for it to point to the real location.