1. Overview of design mode
- [concept] some writing methods of code: flexible program and convenient maintenance; But the code is obscure and not easy for others to take over.
2. Single case design mode
- [concept]: there is one or some special class in the whole project. Only one object belonging to this class can be created.
3. Shared data analysis and solution of single case design mode
3.1 suggestions
- It is suggested that in multithreading, the singleton class should be defined and initialized in the main thread in advance.
- If the variables in the singleton class are read-only, the read-only shared data does not need to be locked.
- If you need to create a singleton class object in a child thread and there are more than one such thread, the initialization will be hit and executed multiple times. Solution: increase mutual exclusion
//.cpp //The private static variable of the class can be called directly from the outside?? std::mu_tex my_tex; //Thread entry function void my_thread(){ A* my_a=A::getInstance(); //... } class A{ public: static A * getInstance(){ /* Why judge twice? 1. If if (m_instance!=NULL) is true, it must indicate that it has been initialized; 2. However, if if (m_instance==NULL) is true, M is uncertain_ Instance status, because it is likely that thread 1 is judged as yes. When preparing new, thread 2 is judged as yes, If new is also prepared, the two threads will new twice. */ if (my_instance==NULL){//Method 2: double locking unique_lock<mutex> thread_mutex(my_tex);//Method 1, low efficiency, solves the problem that different threads collide with the same initialization if(my_instance==nullptr){ my_instance=new A(); static My_garbage gb;//When calling the destructor of this class, the new my_instance is deleted. } } return my_instance; } private: static A *my_instance; A();//! Privatization constructor, that is, there can only be one such class globally. ~A(); }; class My_garbage{ //!!! Ingenious design, you can delete the unknown new variable. public: My_garbage(){}; ~My_garbage(){ if(A::my_instance){ delete A::my_instance; A::my_instance=nullptr; } } }; //*******************.h //Class static variable initialization A *A::my_instance==nullptr; A::A(){} A::~A(){} A::test(){ cout<<"test"<<endl; } int main(){ thread my_t1(my_thread); thread my_t2(my_thread); my_t1.join(); my_t2.join(); return;
4. call_once() function template
-
The second parameter of the function introduced by c + + is a function named a();
-
!!! call_ The once () function ensures that function a() is called only once. No matter how many threads call this function.
-
call_once has the ability of mutex and consumes less resources than mutex in efficiency.
-
It needs to be used in combination with the tag, which is marked as std::once_flag; Actually once_flag is a structure.
-
call_once is used to determine whether the corresponding function a() is executed and call_once successful, call_once sets the flag to the called state, and then calls it again, then the corresponding function a() will not be executed again.
-
Using call_once to implement singleton mode
std::once_flag my_flag;//System defined tags //... class A{ private: static A* my_instance; A(){} public: static void creatInstance(){ //This function is called only once my_instance=new A(); static my_garbage my_g; } static A* getInstance(){ //This method should be called every time_ Once judge my_ Whether instance has been defined. call_once(my_flag,creatInstance()); return my_instance; } };
4, Supplement
Differences between static variables and local variables
- (1) All global variables are static variables; A local variable is a local static variable only if it is defined with the type modifier static.
- (2) A static variable does not mean that its value remains unchanged, but that its value is variable. It's static because it doesn't follow the function
Change due to call and exit, that is, if we give a value to the static variable when the function is called last time, the next time the function is called,
This value remains unchanged. - (3) Differences between static local variables and auto automatic variables
- 3.1 both of them can only be used inside the function, and the function cannot be used again; However, the auto variable will disappear as the function exits, and the static local variable will always exist, but it cannot be used outside the function,
When the function can only be called again, it retains the value of the last call and can continue to be used. - 3.2 static variable initialization statement only needs to be used in the first call; The auto variable is reinitialized every time the function is called.
- 3.3 static variable initialization must be constant or constant expression. If there is no assignment during definition, the system will automatically assign the initial value of 0 (numeric variable is 0, character variable is character variable);
auto variable has no initial value, and its value will be an uncertain value. - 3.4 when a function is called multiple times and the value of some variables is required to be maintained between calls, consider using static local variables.
Although global variables can also achieve the above purpose, global variables will cause unexpected side effects. It is recommended to use local static variables. - 3.5 local static variables occupy memory for a long time and have poor readability. They are unnecessary and should not be used.
The difference between global variables and local variables
- (1) Different scopes: the scope of global variables is the whole program; The scope of the local variable is the current function or loop.
- (2) Memory storage methods are different: global variables are stored in the global data area and local variables are stored in the stack area.
- (3) The life cycle is different: the life cycle of the global variable is the same as that of the main program, which is destroyed with the destruction of the program; A local variable is inside or outside a function
Inside the loop, it is destroyed when the function exits or the loop exits. - (4) Different ways of use: after global variables are declared, all parts of the program can be used, but local variables can only be used locally,
Internal functions will give priority to local variables and then global variables.