A very difficult thing in C is not easy to see the complexity of the expression from the program code.
The following statement: if (yy.operator = = (xx.getValue ()))) will be extended as follows a C pseudocode:
{
X Temp1 = xx.getValue ();
Y Temp2 = Temp1.operator Y ();
INT TEMP3 = yy.operator = = (TEMP2);
IF (Temp3) ...
Temp2.y :: ~ y ();
Temp1.x :: ~ x ();
}
Object structure and deconstruction
The constructor is typically called after the object is constructed, and the deconstructive function must be placed in each offset point (at that time Object also survived) only call. In general, we will put Object as possible around the program segment using it, so you can save unnecessary objects generate operation and destruction.
Global object
C guarantees that the global variable is constructed before the Global variable is used in the main () function, and the Global variable is destroyed before the main () function ends. A global object If there is Constructor and Destructor, we say that it needs a static initialization operation and memory release operation.
Object in static initialization has some shortcomings:
1. If Exception Handling is supported, those Objects will not be placed within the TRY section.
2. In order to control the complexity that is pulled out of the dependent order of Objects, you need to cross the module.
So don't use the Global Objects that requires static initialization.
Partial static object
Its Constructor and Destructor must only be implemented once, although the above functions may be called multiple times.
The local static objects is only constructed when the function containing the Local Static Objects is called.
Their Destructors sequence is also opposite to the call sequence of Constructors.
Object array
Vec_new () and vec_delete () functions will be called to call the constructor and Destructor for each object in an array one by one.
Such as: Point Knots [10];
Will call:
Vec_new (& Knots, Sizeof (Point), 10, & Point :: Point, 0);
New and delete operators
Such as: int * pi = new int (5);
In fact, it is divided into two steps:
INT * PI;
IF (pi = _new (sizeof (int)))
* pi = 5;
Configure a Class Object with constructor, the situation is similar:
Point3d * Origin = new POIT3D;
become:
Point3d * Origin;
IF (Origin = _new (Sizeof (Point3D))))
Origin = point3d :: Point3d (Origin);
If exception handling is realized, the result of conversion may be more complex:
IF (Origin = _new (SizeOf)) {
Try {
Origin - Point3D :: Point3d (Origin);
}
Catch (...) {
_Delete (Origin);
Throw;}
}
}
The application of DESTRUCTOR is very similar:
Delete Origin;
It will become:
IF (ORIGIN! = 0) {
Point3d :: ~ Point3d (Origin);
_Delete (Origin);
}
The general library has two exquisite things for the implementation of the New operator:
Extern void * Operator new (size_t size)
{
IF (size == 0)
SIZE = 1; // For each of the unique pointers per pass.
Void * last_alloc;
While (! (Last_alloc = Malloc (size))))))
{
if (_new_handler) // Allows the user to provide a _new_handler () function belonging to your own.
(* _new_handler) ();
Else
Return 0;
}
RETURN LAST_ALLOC;
}
NEW language for arrays
Such as: int * p_array = new int [5];
become:
INT * p_Array = (int *) _new (5 * sizeof (int));
If there is a New language of the object array of constructor functions:
Point3D * p_Array = New Point3D [10];
become:
POINT3D * P_Array;
P_Array = vec_new (0, sizeof (Point3D), 10, & Point3d :: Point3D, & Point3D :: ~ Point3D);
It is best to avoid arguments with a Base Class Objects to point to a DeriveD Class Objects - if Derived Class Object is larger than its Base. Derived Class's Destructor function is not called because during Delete. If you write, write the base class pointer to the Derived Class pointer in Delete.
Placement Operator New
Point2w * ptw = new (arena) Point2W;
The actual code is:
POINT2W * PTW = (Point2w *) ARENA;
IF (PTW! = 0)
PTW-> Point2w :: Point2W ();
When you want to construct new objects on an original Operator in the original Object, the existing Object has a DEStructor, then you should use Placement Operator Delete to call its Destructor.
C says ARENA must point to the same type of Class, or it is a fast "fresh" memory, enough to accommodate the object of this type. However, Derived Class is obviously not supported. For a DeriveD Class, or other types of not associated, it is not unlaminated, but it is not defined.
"Fresh" storage space can be configured such:
Char * arena = new char [sizeof (point2w)];
Object of the same type can be obtained;
Point2w * arena = new point2w;
Placement New Operator does not support polymorphism. The pointer to the New should appropriately point to a pre-configured memory.
Temporary objects In some environments, it is necessary to have a temporary object from Processor or more convenient. Such a temporary object is defined by a compiler.
Initialization operation:
T c = a b; // will not produce temporary objects
A total compiler is more efficient than the following operations:
c = a b; // will generate temporary objects
A B; // also produces temporary objects
The destruction of the temporary object should be the last step in the full expression. This intact expression causes a temporary object.
. . . . . . Any temporary object containing the results of the expression should be stored in the initialization operation of the Object.
If a temporary object is bound to a Reference, the object will remain until the end of the life of the REFERENCE is ended, or until the end of the temporary object is ended - as the situation arrives first.