In C #, the static constructor of a class is used for initialization before the class is used. For example, it initializes static members or performs specific operations. The CLR automatically calls the static constructor when it first creates the class object or calls the class static method. At the same time, CLR ensures the thread security of the static Constructor (specifically, it is called only once, and there is no multithreading problem ).
The following describes the characteristics of static constructor in MSDN:
1. The static constructor neither has an access modifier nor a parameter
2. Before creating the first instance or referencing any static member, the static constructor is automatically called to initialize the class.
3. The static constructor cannot be called directly.
4. In the program, users cannot control when to execute static constructor.
The C ++ language specification does not include anything similar to a static constructor, but the requirement for initialization before using classes exists objectively. To meet the requirements, C ++ can be implemented manually, but initialization time and thread security should be well handled. This article attempts to simulate static constructor through the C ++ template mechanism to avoid the tedious Implementation of manual initialization. For Class A that requires A static constructor, you only need to inherit the static_constructable <A> template class and provide the static void statici_constructor () method:
Class A: static_constructable <A>
{
Public:
Static void static_constructor (){
Std: cout <"static constructor a" <std: endl;
S_string = "abc"; // initialize static data
}
Static std: string s_string;
Public:
A (){
Std: cout <"constructor a" <std: endl;
}
Private:
Int m_ I;
};
Std: string A: s_string;
Int _ tmain (int argc, _ TCHAR * argv []) {
Std: cout <"beginning of main" <std: endl;
Assert (sizeof (A) = sizeof (int); // inheritance does not change A's memory Layout
Assert (A: s_string = "");
A a1;
Assert (A: s_string = "abc ");
A a2;
Std: cout <"end of main" <std: endl;
Return 0;
}
Output:
Beginning of main
Static constructor a // The static constructor is automatically called once and only once before object A is created.
Constructor
Constructor
End of main
The following is the implementation of the static_constructable class template:
Template <typename T>
Class static_constructable
{
Private:
Struct helper {
Helper (){
T: static_constructor ();
}
};
Protected:
Static_constructable (){
Static helper placeholder;
}
};
In the above implementation, the callback for A: static_constructor () is put into the constructor of the internal class helper, and A helper local static variable is defined in static_constructable <A>; C ++ makes sure that when constructing the object of the derived class A, the base class static_constructable <A> constructor is called first, and the static local variable is constructed only once, in this way, A: static_constructor () is called once and only once. </Span>
The static_constructor class template simulates the static constructor mechanism of c #, which has the following features:
1. automatically call the static constructor provided by the class before constructing the class object for the first time.
2. The time when the static constructor is called is determined.
3. the local static variable initialization mechanism of c ++ ensures thread security (correct: it is not thread security, and the C ++ standard does not involve multithreading, generally, the implementation of the compiler is NOT thread-safe. For more information, see the comments section)
4. The Inheritance-based implementation mechanism does not change the object memory layout of the derived class.
However, compared with the features of the C # static constructor listed in this article, this implementation has obvious shortcomings: the static constructor cannot be triggered by calling the static method of Class; the static constructor of Class A must be public. If you wish to have a better solution, please give us some advice. You are also welcome to discuss this topic with others!