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