stl源碼學習(版本2.91)--list

stl源碼學習(版本2.91)--listnode

一,閱讀list()構造函數的收穫

1,默認構造函數的做用和被調用的時機c++

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

struct A{
  no n;
};

int main(){
  A a;
}

這段代碼報錯,提示沒法構造A類的a對象,編譯器會給A類提供默認構造函數,可是A類的默認構造函數去構造它成員no類的n時,發現no類沒有構造函數(理由:由於本身定義了no(int)構造函數,因此編譯器就不提供no類的默認構造函數了),因此就沒法構造n對象,也就沒法構造a對象了。微信

知識點:

  • 若是類沒有本身提供構造函數,則編譯器會提供一個默認構造函數
  • 當類A裏的成員裏有類成員b時,當構造A時,就會去找b的構造函數,若是類b有構造函數或者默認構造函數則構造b成功。
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,allocator和定位new的用法函數

  • allocator:用於開闢內存空間,可是不調用構造函數
  • 定位new:不開闢內存空間,只調用構造函數

stl_list.h源碼節選學習

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;//list惟一的成員,是end()函數的返回值
  
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.hcode

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.horm

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

從以上的stl list源碼能夠看出:對象

  • list的構造函數list(),只開闢了node的內存空間,並無構造node裏的data對象。理由:這個node的哨兵node不是list裏保存數據的節點。
  • 但調用insert方法時,會調用create_node,這裏面既開闢了節點的內存空間(經過調用get_node();)又調用了節點裏data的構造方法(經過調用construct(&p->data, x);),而後在construct裏使用了定位new(new (p) T1(value);)
  • stl裏開闢空間和構造對象是分開的
  • stl裏使用專用的allocator類來開闢空間

c/c++ 學習互助QQ羣:877684253

本人微信:xiaoshitou5854

相關文章
相關標籤/搜索