STL source code analysis - Configurator Space Allocator # 1 is configured destructor

  STL is concerned with the use of angles, space allocation is what most needs no introduction, as it plays a role behind the scenes, all hidden in a container behind the scenes work. But in order to achieve the angle of the STL, the most should be the first to introduce is the space configurator, it is because it is the cornerstone of the operation of all vessels expand. Space allocation is the name suggests is to configure the device space, to find a place to settle down (memory) for the information stored in the container.

  There are two spaces configured on SGI STL, is a std :: allocator, is a std :: alloc, simply put the former base memory configuration / release behavior (:: operator new and :: operator delete) made a layer simple package, without summary; the latter is the subject we should focus on learning.

  In general, memory configuration and release operation C ++ is this:

1 class Foo {...};
2 Foo* pf = new Foo;
3 delete pf;

  Wherein the new operation comprises two stages: (1) call :: operator new allocated memory; (2) call Foo :: Foo () object content structure. delete operation also includes two stages: (1) call Foo :: ~ Foo () object destructor; (2) :: operator delete call release memory. .

  :: alloc in the same way, the memory configuration by the operator in charge std alloc :: allocate (), is responsible for the release of the alloc :: deallocate (); responsible for the operation object constructor :: construct (), the destructor :: destroy ( )Be responsible for. The function of these two groups in two separate header file, and the file has two heads are <memory> included:

  •   Configuration and release #include <stl_alloc.h> // responsible for memory space
  •   #incluce <stl_construct.h> // constructor and target content responsible destructor

 

 

   From this figure it can be seen that substantially filter spatial configuration profile, herein before starting learning space on an object in the configuration structure and destructor from <stl_construct.h>.

  

. 1  // <stl_construct.h> of Part 
2  
. 3 #include < new new .h>         // To use the placement new, the need to include this file containing 
. 4  
. 5 Template < class Tl, class T2>
 . 6 inline void Construct (Tl * p, const T2 & value) {
 . 7    new new (p) Tl (value);      // Placement new new; Tl :: arouse Tl (value); 
. 8  }
 . 9  
10  / * new new (p) Tl (value); refers to p T1 constructor call on the memory referred to in the subject which produces p stored in the memory referred to. And T1 :: T1 (value); constructor described shape parameter is T1 const T2 & (often a reference variable of type T2). * / 
11  
12 // The following is the destroy () first version, accepting an indicator. 
13 is Template < class T>
 14 inline void the destroy (T * pointer) {
 15      Pointer-> ~ T ();     // evoke T ~ dtor () 
16  }
 . 17  
18 is  // The following is a destroy () a second version, accept the two iterator. This function is to try to find out the numerical elements do not,
 19  // and then use __type_traits <> to strike the most appropriate measures. 
20 is Template < class ForwardIterator>
 21 is inline void the destroy (ForwardIterator First, Last ForwardIterator) {
 22 is    __destroy (First, Last, the value_type (First));
 23 is  }
 24 
25  // Analyzing element typed value (value type) whether there destructor Trivial 
26 is Template < class ForwardIterator, class T>
 27 inline void __destroy (ForwardIterator First, Last ForwardIterator, T * ) {
 28    typedef typename __type_traits <T> :: trivial_destructor has_trivial_destructor;
 29    __destroy_aux (First, Last, trivial_destructor ());
 30  }
 31 is  
32  // If not numerical element (value type) has destructor ... Trivial-non 
33 is Template < class ForwardIterator>
 34 is inline void 
35 __destroy_aux (ForwardIterator First, Last ForwardIterator, __false_type) {
 36    for (; First <Last; ++ First)
 37 [      the destroy (& * First);
 38 is  }
 39  
40  // If not numerical element (value type) have trivial destructor ... 
41 is Template < class ForwardIterator> 
 42 is inline void __destroy_aux (ForwardIterator, ForwardIterator, __true_type) {}
 43 is  
44 is  // the following is a destroy () for the second version of the iterator wchar_t * char * and the specialization of 
45 inline void the destroy ( char *, char * ) {}
46 inline void destroy(wchar_t*, wchar_t*) {}

  construct () and destroy () schematically

  construct () accepts a pointer to an initial value and p value, the role of this function is to invoke the constructor function value space to generate the object indicated by the pointer as an argument. About placement new knowledge can browse this blog .

  destroy () has two versions, the first version is very simple, the destructor of the object can be called directly. While the second version is somewhat more complex, should [first, all the objects within the last) range destructor off, a problem involved here, if a wide range, but each object destructors are irrelevant, so again and again to call the destructor these innocuous can cause loss of performance. Thus, where firstly the value_type () to get the kind referred iterator object reuse __type_traits <T> This type of determination whether the destructor irrelevant. If (__true_type), do nothing; if not (__false_type), this cyclic manner through the entire range of the interval, and each object individually calling the destructor. As for how to get the type referred to in the iterator object, and determines how irrelevant whether the destructor will be mentioned learning programming trait.

 

Guess you like

Origin www.cnblogs.com/MisakiJH/p/11642342.html