Static and static keywords in C ++
Static means static. Here I want to systematically describe the role of the static keyword. Of course, it mainly describes the role of the static keyword in the development languages C and C ++. For other functions, please find additional information. There must be something inappropriate in the explanation. Please be bold in throwing bricks and don't be soft. The content in this article references a lot of online materials.
Static has two main usage methods: process-oriented design and object-oriented design. The former mainly involves the usage of variables and functions. The latter also includes the usage of the former and the usage of the class.
I. static (C language) in process-oriented design)
When talking about the static usage in process-oriented design, let's start with an episode. Historically, the C program has always been composed of the following parts:
Body section
The machine commands executed by the CPU. Generally, the body segment can be shared, so even if it is a regular environment pointer environment, the Environment string execution program of the table (such as text editing program, C Compilation Program, s h e l, etc) there is only one copy in the memory. In addition, the body segment is often read-only to prevent the program from modifying its own commands due to accidents.
Initialize Data Segment
This section is usually called a data segment, which contains the variables in the program that need to be assigned an initial value. The initialized global variables and static variables are stored here. For example, in the C program, description other than any function: int maxcount = 99; stores this variable in the initialization data segment as an initial value.
A. initialized global variables
B. initialized static variables
Non-initialized Data Segment
This section is usually called the bss section, which is derived from an operator of the early assembler, meaning "block started by symbol (block starting with the symbol )", uninitialized global variables and static variables are stored here. Before the program starts to run, the kernel initializes this segment to 0. Description outside the function: long sum [1000]; stores this variable in non-initialized data segments.
A. uninitialized global variables
B. uninitialized static variables
Heap
It must be assigned to the programmer for release management. If the programmer does not release the program, it may be recycled by the OS at the end of the program. It is usually used for dynamic storage allocation in the heap. For example, functions such as malloc, calloc, and realloc in the program are allocated from this. Heap is allocated from bottom up.
Stack
The release manager is automatically assigned by the compiler. Local variables and the address returned during each function call, as well as the caller's environment information (such as some machine registers) are stored in the stack. The newly called function automatically allocates storage space for it and temporary variables on the stack. By using the stack in this way, the C function can be called recursively. Every time a recursive function calls itself, a new stack frame is used. Therefore, variables in one function call instance will never affect variables in another function call instance.
A. Local Variables
B. Return address for function calling
C. Caller's environment information (for example, some machine registers)
Here I will first talk about the static internal mechanism and advantages. I originally wanted to put it in object-oriented design, but its importance has changed the original intention:
Static internal mechanism:
Static data members must exist at the beginning of the program. Because the function is called during the running of the program, static data members cannot allocate space and initialize it in any function.
In this way, there are three possibilities for its space allocation. One is the header file of the class's external interface, where there is a class declaration; the other is the internal implementation of the class definition, there is a member function definition for the class, and the third is the global data description and definition before the main () function of the application.
Static data members must actually allocate space, so they cannot be defined in the class declaration (only data members can be declared ). The class declaration only declares the "size and specification" of a class and does not actually allocate memory. Therefore, it is wrong to write a definition in the class declaration. It cannot be an external definition of the class declaration in the header file, because it will duplicate the definition in multiple source files that use the class.
Static is introduced to inform the compiler that the variables are stored in the static storage area of the program rather than the stack space. static data members are initialized in sequence according to the sequence in which they appear. Note that when static members are nested, make sure that the nested members have been initialized. The order of cancellation is the reverse order of initialization.
Static advantages:
Memory can be saved because it is public to all objects. Therefore, for multiple objects, static data members only store one object for sharing. The value of a static data member is the same for each object, but its value can be updated. You only need to update the value of the static data member once to ensure that all objects have the same value after the update, which improves the time efficiency.
Static local variable
Static local variables are stored in static mode and have the following features:
(1) the lifetime of a static local variable is defined as the entire life cycle of the program in the function, but its scope is still the same as that of an automatic variable. It can only be used in the function that defines the variable. After exiting the function, although the variable still exists, it cannot be used.
(2) If an initial value is not assigned to a static local variable of the basic type during declaration, the system automatically assigns the value 0. If the initial value is not assigned to the automatic variable, the value is not fixed.
According to the characteristics of static local variables, we can see that it is a life cycle for the whole program. Although this function cannot be used after it is defined, it can continue to be used when the function is called again, and the value left after the previous call is saved. Therefore, when you call a function multiple times and require that the values of some variables be retained between calls, you can consider using static local variables. Although global variables can also achieve the above purpose, global variables sometimes cause unexpected side effects, so it is best to use local static variables.
#include <stdio.h>#include <stdlib.h> void Test(){ static int tmpValue = 0; printf("value = %d\n", ++tmpValue);} int main(){ for(int index = 0; index < 50; ++index) { Test() } getchar(); return 0;}
Global Variables
The description of global variables (external variables) is preceded by static to form a static global variable. Global variables are static storage, and static global variables are also static storage. The two are not different in storage methods.
The difference between the two is:
(1). The scope of non-static global variables is the entire source program. When a source program is composed of multiple source files, non-static global variables are valid in each source file.
(2). The static global variable limits its scope. That is, it is valid only in the source file defining the variable and cannot be used in other source files of the same source program. Because the scope of static global variables is limited to one source file, they can only be shared by functions in the source file. Therefore, errors in other source files can be avoided.
From the above analysis, we can see that after changing a global variable to a static variable changes its scope and limits its scope of use.
Static Function
A function defined in a source file can only be called by functions in this file, but cannot be called by functions in other files of the same program. Such functions are called static functions and static functions.
To define a static function, you only need to add a "static" keyword before the function type, as shown below:
Static function type function name (function parameter table ){......}
The keyword "static" is "static" in Chinese. Therefore, internal functions are also called static functions. However, the meaning of "static" here is not the storage method, but the scope of the function is limited to this file.
The advantage of using internal functions is that when different people write different functions, you don't have to worry about whether your own defined functions will have the same name as the functions in other files, because the same name does not matter.
Ii. static (C ++ language) in Object-Oriented Design)
Static Data Member
Add the keyword static before the declaration of the data member in the class. The data member is the static data member in the class. Here is an example of a static data member.
# Include <stdio. h> # include <stdlib. h> class Test {public: Test (){}~ Test () {} Test (const Test & t) {if (this! = & T) {this-> m_nTest1 = t. m_nTest1; this-> m_nTest2 = t. m_nTest2; this-> m_nTest3 = t. m_nTest3 ;}} Test & operator = (const Test & t) {if (this! = & T) {this-> m_nTest1 = t. m_nTest1; this-> m_nTest2 = t. m_nTest2; this-> m_nTest3 = t. m_nTest3;} return * this;} void PrintOut () {// printf ("test_1 = % d test_2 = % d test_3 = % d \ n", m_nSTest1, m_nSTest2, m_nSTest3); // error printf ("test_1 = % d test_2 = % d test_3 = % d \ n", m_nTest1, m_nTest2, m_nTest3);} static void PrintStatic () {printf ("test_1 = % d test_2 = % d test_3 = % d \ n", m_nSTest1, m_nSTest2, m_nSTest3 ); // printf ("test_1 = % d test_2 = % d test_3 = % d \ n", m_nTest1, m_nTest2, m_nTest3); // error} public: int m_nTest1; static int m_nSTest1; protect: int m_nTest2; static int m_nSTest2; private: int m_nTest3; static int m_nSTest3;}; int Test: m_nSTest1 = 10; int Test: m_nSTest2 = 20; int Test: m_nSTest3 = 30; int Test: m_nSTest1 = 10; int main () {Test t; t. printOut (); // t. printStatic (); // Error Test: PrintStatic (); getchar (); return 0 ;}
Static data members have the following features:
(1). For non-static data members, each class object has its own copy. Static data members are treated as class members. No matter how many objects are defined for this class, static data members also have only one copy in the program, which is shared by all objects of this type. That is to say, static data members are shared by all objects in the class. For multiple objects in this class, static data members only allocate memory once for all objects to share.
(2) static data members are stored in the global data zone. Space is allocated only when the static data member is defined, so it cannot be defined in the class declaration. In the preceding example, the Statement int Test: m_nSTest1 = 10 is a static data member;
(3) static data members follow the public, protected, and private access rules like common data members;
(4 ). because static data Members allocate memory in the global data zone and all objects in this class are shared, they do not belong to a specific class object and are visible in the scope when no class object is generated, that is, when no class instance is generated, we can operate on it;
(5) static data member Initialization is different from general data member initialization. Static data member initialization format: <data type> <class name >::< static data member name >=< value> For example: int Test: m_nSTest1 = 10;
(6 ). static data members of a class can be accessed in two forms: <Class Object Name>. <static data member name> or <class type name >:< static data member name>
(7). static data members are mainly used when each object has the same attribute. For example, for a deposit type, the interest of each instance is the same. Therefore, the interest should be set as the static data member of the deposit class. There are two advantages: first, no matter how many deposit-type objects are defined, interest data members share the memory allocated to the global data area, thus saving storage space. Second, once the interest needs to be changed, the interest of all deposit objects will be changed once;
(8). Compared with global variables, using static data members has two advantages:
A. The static data member does not enter the global namespace of the program, so there is no possibility of conflict with other global names in the program;
B. Information can be hidden. Static data members can be private members, but global variables cannot;
Static member functions
# Include <stdio. h> # include <stdlib. h> class Test {public: Test (){}~ Test () {} Test (const Test & t) {if (this! = & T) {this-> m_nTest1 = t. m_nTest1; this-> m_nTest2 = t. m_nTest2; this-> m_nTest3 = t. m_nTest3 ;}} Test & operator = (const Test & t) {if (this! = & T) {this-> m_nTest1 = t. m_nTest1; this-> m_nTest2 = t. m_nTest2; this-> m_nTest3 = t. m_nTest3;} return * this;} void PrintOut () {// printf ("test_1 = % d test_2 = % d test_3 = % d \ n", m_nSTest1, m_nSTest2, m_nSTest3); // error printf ("test_1 = % d test_2 = % d test_3 = % d \ n", m_nTest1, m_nTest2, m_nTest3);} static void PrintStatic () {printf ("test_1 = % d test_2 = % d test_3 = % d \ n", m_nSTest1, m_nSTest2, m_nSTest3 ); // printf ("test_1 = % d test_2 = % d test_3 = % d \ n", m_nTest1, m_nTest2, m_nTest3); // error} public: int m_nTest1; static int m_nSTest1; protect: int m_nTest2; static int m_nSTest2; private: int m_nTest3; static int m_nSTest3;}; int Test: m_nSTest1 = 10; int Test: m_nSTest2 = 20; int Test: m_nSTest3 = 30; int Test: m_nSTest1 = 10; int main () {Test t; t. printOut (); // t. printStatic (); // Error Test: PrintStatic (); getchar (); return 0 ;}
Static member function, which serves all the services of a class rather than the specific objects of a class. A common member function generally implies a this pointer, because a common member function always belongs to a specific object of a class. Generally, this is the default value. For example, the function fn () is actually this-> fn (). However, compared with common functions, static member functions do not have the this pointer because they are not associated with any objects. In this sense, it cannot access the no-static data member of the class object, nor can it access the no-static member function. It can only call other static member functions.
Static member functions can be summarized as follows:
(1). the keyword static cannot be specified for function definitions that appear in external classes;
(2). static members can access each other, including static member functions accessing static data members and static member functions;
(3). Non-static member functions can access static member functions and static data members at will;
(4). static member functions cannot access non-static member functions and non-static data members, but can only access static ones;
(5). Because there is no additional overhead of this pointer, static member functions will increase slightly compared with global functions of the class;
(6 ). call static member functions. You can use the member access operator (.) and (->) call a static member function for a class object or pointer to a class object. You can also directly use the following format:
<Class name >:: <static member function name> (<parameter table>)
For example: Test: PrintStatic (), call the static member function of the class.
However, public, protected, and private access rules must be followed.
Public, protected, and private access rules
First, the access range of the private, public, and protected access labels.
Private: It can only be accessed by 1. functions in this class, 2. Other functions.
Cannot be accessed by any other user, nor can the object of this class be accessed.
Protected: it can be accessed by 1. functions in this class, 2. Sub-class functions, and 3. Its membership functions.
But cannot be accessed by objects of this class.
Public: it can be accessed by 1. functions in this class, 2. Sub-class functions, 3. Its friends functions, or 4. objects in this class.
Note: There are three types of functions: normal non-member functions set as friends, member functions of other classes set as friends, and all member functions in the friends class.
Second, the method property changes after the class is inherited.
Private attributes cannot be inherited.
Using private inheritance, the protected and public attributes of the parent class are changed to private in the subclass;
Using protected inheritance, the protected and public attributes of the parent class are changed to protected in the subclass;
Use public inheritance. The protected and public attributes in the parent class are not changed;
As follows:
Public: protected: private:
Public inherits from public protected and is unavailable.
Protected inherits protected. protected is unavailable.
Private inherits private unavailability
Protected inheritance and private inheritance can reduce access permissions.
To further understand the differences between the three continuous methods in terms of Member visibility, we will discuss them from three different perspectives.
For public continuation:
(1) Visibility of base class members on their objects:
Public members are visible, while others are invisible. Here, the protection of members is the same as that of private members.
(2) Visibility of base class members on Derived classes:
Public and protected members are visible, while private members are invisible. The members are protected in the same way as public members.
(3) Visibility of base class members on derived class objects:
Public members are visible, while other members are invisible.
Therefore, when the public continues, the object of the derived class can access the public members in the base class; the member functions of the derived class can access the public members and protected members in the base class. Here, you must distinguish between the object of the derived class and the member functions in the derived class to access the base class.
For private continuation mode:
(1) Visibility of base class members on their objects:
Public members are visible, while other members are invisible.
(2) Visibility of base class members on Derived classes:
Public and protected members are visible, while private members are invisible.
(3) Visibility of base class members on derived class objects:
All members are invisible.
Therefore, when the private class continues, the base class members can only be accessed by the direct derived class, but cannot continue.
For protection continuation methods:
This continuation method is the same as the private continuation method. The difference between the two lies in that they have different visibility on the base class members for the members of the derived class.
The visibility mentioned above is accessibility. There is another saying about accessibility. In this rule, the object of the derived class uses horizontal access to the base class, and the access of the derived class to the base class is vertical access.
The general rules are as follows:
When the public continues, horizontal access and vertical access are not restricted to the public members in the base class;
When the private key continues, horizontal access and vertical access cannot be accessed by public members in the base class;
When the protection continues, vertical access is the same as public access, and horizontal access is the same as private access.
Private Members in the base class can only be accessed by member functions and friends functions in the base class, and cannot be accessed by other functions.
Relationship between base classes and derived classes
Any class can derive a new class, and the derived class can also generate a new class. Therefore, the base class and the derived class are relative.
The relationship between the base class and the derived class can be described as follows:
1. The derived class is the concrete type of the base class.
The hierarchy of Classes usually reflects a certain real model in the objective world. In this case, it is not difficult to see that the base class is the abstraction of several Derived classes, and the derived class is the embodiment of the base class. The base class extracts the common features of its derived class, and the derived class changes the abstract class to a useful type by adding behavior.
2. The derived class is a continuation of the definition of the base class.
First, define an abstract base class. Some operations in this base class are not implemented. Define a non-Abstract derived class to implement the operations defined in the abstract base class. For example, this is the case for virtual functions. In this case, the derived class is the implementation of the abstract base class and can be seen as a continuation of the definition of the base class. This is also a common method of derived classes.
3. A derived class is a combination of base classes.
When multiple classes continue, a derived class has more than one base class, and the derived class will be a combination of all base class behaviors.
A derived class distinguishes itself from a base class by adding data members and member functions. Therefore, the mechanism will allow you to explain the differences between the new class and the existing class when creating a new class, so that a large number of original program code can be reused, so someone calls a class a reusable software component ".
How to Use the const and static keywords in C?
Const is the abbreviation of constant, which means "constant. All things modified by const are protected by force, which can prevent unexpected changes and improve program robustness.
Const can modify variables, function input parameters, and function return values.
Static: Hide
When we compile multiple files at the same time, all global variables and functions without the static prefix are globally visible.
The second role of static is to keep the variable content persistent. Variables stored in the static data area will be initialized at the beginning of the program, which is also the only initialization.
Static is initialized to 0 by default. In fact, global variables also have this attribute, because global variables are also stored in the static data zone. In the static data area, the default values of all bytes in the memory are 0x00. In some cases, this feature can reduce the workload of programmers.
Static keywords in C Language
The process-oriented static of C ++ is the same as that of C. The static function of C ++ has two usage methods: static in process-oriented programming and static in object-oriented programming. The former applies to common variables and functions, and does not involve classes. The latter mainly describes the role of static in classes.
I. static in process-oriented design
1. Static global variables
Add the keyword static before the global variable, which is defined as a static global variable. Here is an example of a static global variable:
// Example 1
# Include <iostream. h>
Void fn ();
Static int n; // defines the static global variable.
Void main ()
{N = 20;
Cout <n <endl;
Fn ();
}
Void fn ()
{N ++;
Cout <n <endl;
}
Static global variables have the following features:
This variable allocates memory in the global data zone;
Uninitialized static global variables will be automatically initialized to 0 by the program (the values of automatic variables are random unless they are explicitly initialized );
Static global variables are visible in the entire file declared, but invisible outside the file;
All static variables are allocated memory in the global data zone, including the static local variables to be mentioned later. For a complete program, the distribution in the memory is as follows:
Code Area
Global data Zone
Heap Area
Stack Zone
In general, dynamic data generated by new is stored in the heap zone, and automatic variables in the function are stored in the stack zone. Automatic variables usually release space as the function exits, and static data (even static local variables in the function) is stored in the global data zone. The data in the global data zone does not release space because the function exits. Careful readers may find that
Static int n; // defines the static global variable.
Change
Int n; // defines the global variable
The program runs normally.
Indeed, defining global variables can share variables in files, but defining static global variables has the following benefits:
Static global variables cannot be used by other files;
Variables with the same name can be defined in other files without conflict;
You can change the Sample Code as follows:
// Example 2 // File1
# Include <iostream. h>
Void fn ();
Static int n; // defines the static global variable.
Void main ()
{N = 20;
Cout <n <endl;
Fn ();
}
// File2
# Include <iostream. h>
Extern int n;
Void fn ()
{N ++;
Cout <n <endl;
}
Compile and run Example 2, and you will find that the above Code can be compiled separately, but an error occurs during running. Try
Static int n; // defines the static global variable.
Change
Int n; // defines the global variable
Compile and run the program again to understand the differences between global variables and static global variables.
2. Static local variables
Before a local variable, add the keyword static to define the variable as a static local variable.
Here is an example of static local variables:
... The remaining full text>