Constructor and destructor are two seemingly simple types of functions in a class, but some unexpected running errors will always occur during actual use. This article will systematically introduce the principles and application of constructor and destructor in C #, as well as several precautions during use.
I. constructor and destructor principles
As a more advanced language than C, C # provides a better mechanism to enhance program security. C # the compiler has a strict type security check function, which can almost find all the Syntax problems in the program, which indeed helps programmers. However, after the program passes the compilation check, it does not mean that the error does not exist. In the "error" family, the "syntax error" status can only be regarded as the tip of the iceberg. High-level errors are often hidden in depth and cannot be easily discovered.
Based on experience, many program errors that are hard to detect are caused by the variable being correctly initialized or cleared, and initialization and cleanup are easily forgotten. Microsoft fully considered this problem when designing the C # language using the object-oriented concept and solved it well: Put the initialization of the object in the constructor, put the cleanup work in the destructor. When an object is created, the constructor is automatically executed. When an object dies, the Destructor is automatically executed. In this way, you do not have to worry about the initialization and clearing of objects.
II. Application of constructor in C #
The name of the constructor cannot start at will. It must be recognized by the compiler before it can be automatically executed. Its naming method is simple and reasonable: Let the constructor and class have the same name. Except for the name, the constructor has no return value type, which is different from the void function. If it has a return value type, the compiler will be overwhelmed. Before you can access a class's methods, attributes, or anything else, the first statement to be executed contains the constructor of the corresponding class. Even if you do not write a constructor, a default constructor is provided to you.
Class testclass
{
Public testclass (): Base () {}// provided by CLR
}
The following lists several types of constructors.
1) default constructor
Class testclass
{
Public testclass (): Base (){}
}
As described above, it is provided by the system (CLR.
2) instance Constructor
An instance constructor is a method member that initializes an instance in a class. For example:
Using system;
Class Point
{
Public Double X, Y;
Public point ()
{
This. x = 0;
This. Y = 0;
}
Public point (Double X, Double Y)
{
This. x = X;
This. Y = y;
}
...
}
Class Test
{
Static void main ()
{
Point A = new point ();
Point B = new point (3, 4); // use the constructor to initialize the object.
...
}
}
Declares a class point, which provides two constructors. They are overloaded. One is a point constructor without parameters and the other is a point constructor with two double parameters. If the constructor is not provided in the class, the CLR automatically provides a default constructor. However, once a class provides custom constructor, such as point () and point (Double X, Double Y), the default constructor will not be provided.
3) Static Constructor
A static constructor is a method member that initializes a class. It is generally used to initialize static data. Static constructor cannot have parameters, modifiers, and call. When a class is loaded, the static constructor of the class is automatically called. For example:
Using system. Data;
Class employee
{
Private Static dataset Ds;
Static employee ()
{
DS = new dataset (...);
}
...
}
Declared a class of employee with a static constructor. Note: static constructors can only initialize static data members, but not non-static data members. However, non-static constructors can assign values to static data members or initialize non-static data members.
If the class only contains static members, you can create a private constructor: Private testclass (){...}, However, private means that it is impossible to access the constructor from outside the class. Therefore, it cannot be called and no object can be instantiated by the class definition.
The above is a simple application of several types of constructor. The following describes how to use the base class and the constructor of the derived class in the class hierarchy (that is, the inheritance structure. The initialization of a derived class object is completed by the base class and the derived class. The base class members are initialized by the base class constructor, and the members of the derived class are initialized by the constructor of the derived class.
When creating an object of A derived class, the system will call the constructor of the base class and the constructor of the derived class. The execution sequence of the constructor of the base class is: first execute the constructor of the base class, then execute the constructor of the derived class. If the derived class has another object Member, first execute the constructor of the base class, then execute the constructor of the member object class, and finally execute the constructor of the derived class.
As for the constructors that execute the base class, the base class constructor is executed by default. If you want to execute the base class constructor with parameters, it must be specified in the member initialization table of the derived class constructor. For example:
Class
{Private int X;
Public A () {x = 0 ;}
Public A (int I) {x = I ;}
};
Class B:
{Private int y;
Public B () {Y = 0 ;}
Public B (int I) {Y = I ;}
Public B (int I, Int J): A (I) {Y = J ;}
};
B b1 = new B (); // execute the constructor A () of the base class A, and then execute the constructor B () of the derived class ()
B b2 = new B (1); // execute the constructor A () of the base class A, and then execute the constructor B (INT) of the derived class)
B B3 = new B (); // execute the constructor A (INT) of the base class A, and then execute
Constructor B (INT, INT)
Here, the execution sequence of the constructor must be clearly analyzed. In addition, if the base class A does not provide the non-argument constructor public a () {x = 0 ;}, in the initialization table of all constructors in the derived class, the constructors A (I) of the base class A must be pointed out as follows:
Class
{Private int X;
Public A (int I) {x = I ;}
};
Class B:
{Private int y;
Public B (): A (I) {Y = 0 ;}
Public B (int I): A (I) {Y = I ;}
Public B (int I, Int J): A (I) {Y = J ;}
};
Iii. Application of destructor and garbage collector in C #
A destructor is a method member that destroys an instance of a class. The Destructor cannot have parameters, any modifiers, and cannot be called. Because the purpose of the Destructor is opposite to that of the constructor, the prefix '~ 'To show the difference.
Although C # (or CLR) provides a new memory management mechanism-automatic memory management ), resources can be released automatically through the "Garbage Collector". Generally, no user intervention is required. However, in some special circumstances, you still need to use the destructor, for example, release of unmanaged resources in C.
Resources are automatically released through the "Garbage Collector", but there are still some points to note:
1. the reference of the value type and reference type does not need any "Garbage Collector" to release the memory, because when they are out of scope, the occupied memory will be automatically released, because they are all stored in stacks;
2. only the object instances referenced by reference types are stored in heap. Because heap is a free storage space, therefore, it does not have a life period like the "stack" (after the "stack" element pops up, it indicates that the life period ends and the memory is released). Note that, the "Garbage Collector" only applies to this area;
However, in some cases, you must write code to release unmanaged resources. Usually, you can use the destructor to release the unmanaged resources and place the code snippet that you write to release the unmanaged Resources in the destructor. Note that if an unmanaged resource is not used in a class, do not define the Destructor because the object executes the destructor, therefore, the "Garbage Collector" must call the Destructor before releasing the managed resources, and then release the managed resources for the second time. In this way, the cost of the two Delete actions is more than that of the first action. The following code shows how the Destructor is used:
Public class resourceholder
{
...
~ Resourceholder ()
{
// Here is the user code segment for clearing unmanaged Resources
}
}
Iv. Summary
Although constructor and destructor are relatively simple functions in the form of a class, their use is never as simple as it looks, therefore, flexible and correct use of constructors and destructor can help you better understand the CLR memory management mechanism and better manage system resources.