C + + compilation takes a lot of effort to make the use of class and the original class (primitive types) consistent. For example, an array application:
A a[100] ;//A is class
int b[100] ;
Although a is an object of a user-defined class, it is no different than an array of integers. Let's look at the semantic differences.
A is the Pod class (a class with full value semantics)
If a is a PODwith value semantics (see my blog about value semantics: http://www.cnblogs.com/ly8838/p/3929025.html), test shows A There is no difference between the creation and reading and the general variables, of course, there is no difference in performance.
In other words,a a[3] ; and a A1, A2, A3; semantically identical, there is no difference in performance.
A is a class with a default constructor (but no destructor)
We have a simple struct:
struct stackobject
{
int _a;
int _b;
Stackobject (): _a (0), _b (1)
{
}
};
and a simple test function:
void testarraysemantics()
{
Stackobject sa[10]; Line 1: Call Vector constructor iterator
SA [0]._a= 1;
SA [9]._b = 10;
}
When running in vc++2010, we see that Line1 called a compiled-from function. This is a generic "matrix construction cycle (vector constructor iterator)":
Its approximate implementation is as follows:
void Vector_constructor_iterator (
int Array_size,
int Array_element_size,
void (*ctr) (void *addr),
Char *arraystartaddress)
{
for (int i = 0; i < array_size; ++i)
{
void *objaddr = arraystartaddress + i * array_element_size;
CTR (OBJADDR);
}
}
This is a typical C function that invokes the Stackobject constructor as a function pointer.
From this function, it makes a a[3] , and a A1, A2, A3 , the semantics of a fundamental change. Not only do we invoke the function generated by the compilation, but we also use pointers to call Stackobject 's constructor indirectly. The test results show that the "construction " Speed of the array is reduced by about 30%. Considering the application value of array , the decline of this speed is understandable and acceptable.
A is a class with a default constructor and a destructor
With the addition of destructor , the semantics ofa a[10] have changed a new. If you read my previous blog about exception handling (http://www.cnblogs.com/ly8838/p/3961119.html), compile must ensure that all created object"All" is destroyed, so it must "remember "Create a hot spot in the process.
Let's add another dummy class to test the effect of destructor on array:
struct StackObject2
{
int _a;
int _b;
StackObject2 (): _a (0), _b (1)
{
}
~stackobject2 ()
{
_a = _b = 0;
}
};
Our test function is changed to
void testarraysemantics ()
{
clock_t begin = Clock ();
for (int i = 0; i < 100000; ++i)
{
Stackobject sa[3];// line1 : Test without d ' TR
Sa[0]._a= 1;
Sa[1]._b = 2;
Sa[2]._b = 3;
}
clock_t end = Clock ();
Auto spent = double (end-begin)/clocks_per_sec;
printf ("Spent for ' array ' is%f\n", spent);
begin = Clock ();
for (int i = 0; i < 100000; ++i)
{
StackObject2 sa[3];// line2 : Test with d ' TR
Sa[0]._a= 1;
Sa[1]._b = 2;
Sa[2]._b = 3;
}
end = Clock ();
Spent = double (end-begin)/clocks_per_sec;
printf ("Spent for ' array with Dtro ' is%f\n", spent);
begin = Clock ();
for (int i = 0; i < 100090; ++i)
{
Stackobject SA1, SA2, SA3; Line3 : Test without array
Sa1._a= 1;
Sa2._b = 2;
Sa3._b = 3;
}
end = Clock ();
Spent = double (end-begin)/clocks_per_sec;
printf ("Spent for ' None-array ' is%f\n", spent);
}
The line2 above attempts to create an arrayof StackObject2 classes with destructor . At VC + +, we noticed that at this time the compiler produced another name slightly different from the function "eh Vector constructor iterator", but looked at the generated code, found it and vector constructor Iterator is a big difference. Its pseudo-code is roughly the same:
void Vector_constructor_iterator_with_dtor (
int Array_size,
int Array_element_size,
void (*ctr) (void *addr),
void (*DTR) (void *addr),
Char *arraystartaddress)
{
int lastcreated =-1;
Try
{
for (int i = 0; i < array_size; ++i)
{
void *objaddr = arraystartaddress + i * array_element_size;
CTR (OBJADDR);
lastcreated = i;
}
}
catch (...)
{
Destroy partially created array in case or fault
for (int i = 0; I <= lastcreated; ++i)
{
void *objaddr = arraystartaddress + i * array_element_size;
DTR (OBJADDR);
}
}
}
Compare pseudo code We see: The main difference betweenvector_constructor_iterator_with_dtor and Vector_constructor_iterator is that the mechanism of exception handling is increased, A matrix element that is used to destroy "already constructed".
Running testarraysemantics indicates that the array construction speed of the class with destructor has dropped by nearly 300%.
Therefore, the importance of removing unnecessary destructor is once again fully reflected.
Conclusion
C + + The built-in array support for class object is a very important language construct, which is another reflection of C + + 's treatment of class object and primitive variable, which greatly increases C + + of value added.
However, as always, we need an in-depth understanding of the semantics of C + +, a language construct. So that the C + + built-in arrayis used correctly.
Semantics of C + + built-in Array