stl source code learning (version 2.91)--list

Keywords: C++

stl source code learning (version 2.91)--list

First, read the list() constructor

1. The function of the default constructor and the time to be called

struct no{
  no(int i){}
  //no(){
  //  std::cout << "s" << std::endl;
  //}
  long data;
};

struct A{
  no n;
};

int main(){
  A a;
}

This code reports a n error, indicating that class A's a object cannot be constructed. The compiler will provide a default constructor for class A, but when class A's default constructor constructs its member n of class no, it finds that class no has no constructor (reason: because it has defined its own no(int) constructor, the compiler does not provide a default constructor for class no), so it cannot construct an n object, that is to say Unable to construct a object.

Knowledge points:

  • If the class does not provide its own constructor, the compiler provides a default constructor
  • When there is class member b in the member of class A, when constructing a, the constructor of b will be found. If class b has a constructor or the default constructor, the construction of b is successful.
1.cpp: In function 'int main()':
1.cpp:22:5: error: use of deleted function 'A::A()'
   A a;
     ^
1.cpp:12:8: note: 'A::A()' is implicitly deleted because the default definition would be ill-formed:

2. Use of allocator and positioning new

  • allocator: used to open up memory space, but does not call the constructor
  • Locate new: do not open memory space, only call constructor

Excerpt of STL list. H source code

template <class T>
struct __list_node {
  typedef void* void_pointer;
  void_pointer next;
  void_pointer prev;
  T data;
};

template <class T, class Alloc = alloc>
class list {
protected:
  typedef __list_node<T> list_node;
  typedef simple_alloc<list_node, Alloc> list_node_allocator;
public:      
  typedef list_node* link_type;

protected:
  link_type node;//The only member of the list is the return value of the end() function
  
public:
  list() { empty_initialize(); }
protected:
  void empty_initialize() { 
    node = get_node();
    node->next = node;
    node->prev = node;
  }
protected:
  link_type get_node() { return list_node_allocator::allocate(); }
                
  link_type create_node(const T& x) {
    link_type p = get_node();
    __STL_TRY {
      construct(&p->data, x);
    }
    __STL_UNWIND(put_node(p));
    return p;
  }
  S
  iterator insert(iterator position, const T& x) {
    link_type tmp = create_node(x);
    tmp->next = position.node;
    tmp->prev = position.node->prev;
    (link_type(position.node->prev))->next = tmp;
    position.node->prev = tmp;
    return tmp;
  }

stl_alloc.h

template<class T, class Alloc>
class simple_alloc {

public:
    static T *allocate(size_t n)
                { return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); }
    static T *allocate(void)
                { return (T*) Alloc::allocate(sizeof (T)); }

stl_construct.h

template <class T1, class T2>
inline void construct(T1* p, const T2& value) {
  new (p) T1(value);
}

From the above stl list source code, we can see:

  • The constructor list() of list only opens up the memory space of the node and does not construct the data object in the node. Reason: the sentinel node of this node is not the node that stores data in the list.
  • But when the insert method is called, the create node will be called, which not only opens up the memory space of the node (by calling get node();) but also calls the data construction method of the node (by calling construct (& P - > data, x);), and then uses the location new (P) T1 (value);) in construct
  • In stl, space creation and object construction are separated
  • Using special allocator class to open up space in stl

QQ group of mutual learning in c/c + +: 877684253

My wechat: xiaoshitou5854

Posted by aktell on Mon, 04 Nov 2019 16:43:05 -0800