Detail C++ scope and life cycle

  • 2020-11-18 06:23:18
  • OfStack

Nicklaus Wirth, the father of Pascal, once proposed a formula that shows the essence of a program: program = algorithm + data structure. Another formula is given to correspond with it: software = program + document. These two formulas can be concise and show us the composition of the program and software.

The running process of the program can be understood as the processing process of the algorithm to the data, and the running result of the program is the result data generated by the processing data of the algorithm. The algorithm describes the steps of data processing, corresponding to the function in the program. A data structure describes the organization of data in a computer, corresponding to the type of data in a program. Data in a program corresponds to ubiquitous variables. For us programmers, it's all about functions, data types, and variables. Therefore, C++ talks about scope and life cycle for these three components of the program: functions, data types, and variables. 11 is described below.

1. Difference between scope and life cycle

Scope and life cycle are two completely different concepts. In English, the scope is expressed as "scope" and the life cycle as "duration". Scope is a static concept that is only used when compiling a source program. The scope of an identifier is the area in the source file where the identifier can legally appear independently. The life cycle is the concept of one-runtime (Runtime), which refers to the time period of the existence of a variable in the whole process of the program from load to finish running. Since functions and data types are static concepts, they have no life cycle; they exist from compilation to execution to completion.

The scope level in C++ ranges from high to low, mainly including file domain (global scope), namespace domain, class domain, function scope and code block scope, among which function scope and code block scope are collectively referred to as local domain.

2. Scope of the function

Functions are divided into member functions of a class and global functions.

Class member functions:

Scope: Class domain. Life cycle: none (program running period 1 exists directly). Reference method: The dot operator (.) or pointer operator (-) is used in other files > ) or the scope operator (::) to reference. Memory distribution: Code area. Note: Class member functions can be defined in the body of the class, that is, in the header file, and no redefinition errors will be reported when the class is contained in different source files, because the functions implemented in the body of the class have inline features.

Examples are as follows:


//main.cpp
class test
{
private:
 int i;
public:
 void show()
 {
 cout<<"i:"<<i<<endl;
 }
};
int main(int argc,char* argv[])
{
 test t;
 t.show()
}

Global function:

Scope: File domain (global scope). Life cycle: none (program running period 1 exists directly). Reference methods: Function prototype declarations are made in other files before they are used. Memory distribution: Code snippets. Note: If a global function with the same name is defined in two source files, a redefinition error occurs when you connect.

Examples are as follows:


//function.cpp
void printHello()
{
 cout<<"hello world"<<endl;
}

//main.cpp
void printHello();
int main(int argc,char* argv[])
{
 printHello();
}

3. Scope of data types

Data types in C++ can be divided into basic data types and non-basic data types, while non-basic data types can be divided into composite data types and constructed data types. For the data types in C++, please refer to blog: C++ data types in another article of the author.

Basic data types:
Basic data types include integers (int), real types (float and double), characters (char), booleans (bool), and valueless types (void).

Scope: File domain (global scope). Life cycle: none (program running period 1 exists directly). Reference method: No need to declare, use directly. Memory distribution: Code snippets.

Composite data type:

The composite data types include arrays (type[]), Pointers (type*), and references (type) & Enumeration (enum).

If the composite data type is a composite in which the construction data type participates, its scope is the same as that of the construction data type 1. The scope of the enum enumerated type is the same as that of the construct type.

Construct data type:

Scope: The field in which the type definition is located. Other files are not visible. Life cycle: none (program running period 1 exists directly). Reference methods: Defined in other files before being used by scope operators. Memory distribution: Code area. Note: As long as the files do not contain each other, no redefinition errors will occur if constructs with the same name are defined in both source files, because the data types have no external connectivity.

Examples are as follows:


//main.cpp
namespace dd
{
 class test
 {
 private:
 int i;
  public:
 void show()
   {
   cout<<"i:"<<i<<endl;
   }
 };
}
using namespace dd;// References the constructed types in the namespace domain test Cannot be used otherwise 
int main(int argc,char* argv[])
{
 test t;
 t.show();
}

4. Scope and life cycle of variables

The variables we face are mainly divided into global variables, global static variables, local variables and local static variables. The following 11 describes their scope and lifecycle.

Global variables:

Scope: Global scope (global variables are defined in one source file and can be applied to all source files); Life cycle: program running period 1 exists; Reference methods: Global variables that must be declared with the extern keyword to be referenced are used in other files. ; Memory distribution: Global/static storage; Note: If global variables with the same name are defined in both files, connection error: variable redefinition.

Examples are as follows:


//define.cpp 
int g_iValue = 1; 
 
//main.cpp 
extern int g_iValue; 
 
int main() 
{ 
  cout << g_iValue; 
  return 0; 
} 

Global static variables:

Scope: File scope (visible only in defined files); Life cycle: program running period 1 exists; Memory distribution: Global/static storage; Definition method: static keyword, const keyword; Note: It is possible to define exactly the same two static variables in two different files, as long as the files do not contain each other. They are completely different variables.

Examples are as follows:


//define.cpp 
const int iValue=8;  

//main.cpp
int iValue; 
static const int iValue_2; 
static int iValue_3; 
int main(int argc,char* argv[])
{
 cout<<"iValue:"<<iValue<<endl;
 return 0;
}

Local variables:

Scope: local scope (visible only in local scope, e.g., function domain, code block domain); Life cycle: The program is destroyed when it runs out of the local scope; Memory distribution: stack area; Note: the auto indicator is indicated.

Examples are as follows:


void print()
{
 int a=0;
 cout<<a<<endl;
}

Local static variables:

Scope: local scope (visible only in local scope); Life cycle: program running period 1 exists; Memory distribution: global static storage; Definition method: local scope is defined with static; Note: it is initialized only once. Lock protection is required for multithreading.

Examples are as follows:


void function() 
{ 
  static int iREFCounter = 0; 
} 

5. Expand your knowledge

5.1 Variable storage type descriptors

The C language provides four storage type descriptors auto, register, extern and static. The four storage types have two storage terms: automatic storage term and static storage term. auto and register correspond to the automatic storage period. The modified variable is created when entering the block declaring the variable, exists when the block is active, and is revoked when exiting the block. Variables in the static storage period exist from the time the program is loaded and run until the end of the program 1.

5.2 Suggestions for static

(1) If the global variable is only accessed in a single C file, the variable can be modified to a static global variable to reduce the coupling between modules;
(2) If the global variable is only accessed by a single function, the variable can be changed into the static local variable of the function to reduce the coupling degree between modules;
(3) When designing and using functions that access dynamic global variables, static global variables and static local variables, the reentrant problem needs to be considered, because they are all placed in the static data store and can be Shared by other functions;
(4) If we need a reentrant function, we must avoid using the static variable in the function. Such functions are called functions with an "internal memory" function;
(5) static variable must be used in the function: for example, if the return value of a function is pointer type, it must be the address of local variable of static as the return value; if it is auto, it must be a wild pointer.

These are the details of C++ scope and life cycle. For more information on C++ scope and life cycle, please follow the other articles on this site!


Related articles: