• 欢迎浏览“String me = Creater\忠实的资深Linux玩家;”,请文明浏览,理性发言,有侵犯你的权益请邮件我(creater@vip.qq.com).
  • 把任何的失败都当作一次尝试,不要自卑;把所有的成功都想成是一种幸运,不要自傲。
  •    5年前 (2013-05-01)  STL |   2 条评论  16 
    文章评分 0 次,平均分 0.0

    list默认使用alloc作为空间配置器,alloc是什么?可以参考前面的文章,其实在这里可能是第一级空间配置器,也可能是第二级空间配置器。

    template
    class list {};

    还是那样为了满足标准,需要对配置器包装,在list中成为list_node_allocator.

      typedef simple_alloc<list_node, Alloc> list_node_allocator;
    

    所以list中就使用list_node_allocator作为配置器。可以如下使用:

    list_node_allocator::allocate();
    list_node_allocator::deallocate(p)

    下面来看看list中节点的构造。
    首先看如何配置一个节点空间,并传回地址:

     link_type get_node() { return list_node_allocator::allocate(); }1
    再来看如果释放一个节点空间:
    1 void put_node(link_type p) { list_node_allocator::deallocate(p); }

    那么在list中,如何来构造一个list节点,首先配置空间,然后在返回的空间上构造。

      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;
      

    如何啦析构一个list节点,首先调用析构函数销毁在该内存中的对象,再释放该空间。

      void destroy_node(link_type p) {
        destroy(&p->data);
        put_node(p);
      

    注意其中的:construct,destroy这两个全局函数。可以点击这里

    list的构造函数比较多

     
    list() { empty_initialize(); 
    }
    list(size_type n, const T& value) { fill_initialize(n, value); }
      list(int n, const T& value) { fill_initialize(n, value); }
      list(long n, const T& value) { fill_initialize(n, value); }
      explicit list(size_type n) { fill_initialize(n, T()); }
    
    #ifdef __STL_MEMBER_TEMPLATES
      template <class InputIterator>
      list(InputIterator first, InputIterator last) {
        range_initialize(first, last);
      }
    
    #else /* __STL_MEMBER_TEMPLATES */
      list(const T* first, const T* last) { range_initialize(first, last); }
      list(const_iterator first, const_iterator last) {
        range_initialize(first, last);
      }
    #endif /* __STL_MEMBER_TEMPLATES */
      list(const list<T, Alloc>& x) {
        range_initialize(x.begin(), x.end());
      }
    

    当我们使用list mylist;定义一个list的时候,调用的构造函数为

    list() { empty_initialize(); }

    这个就产生了只有一个空白节点的list,该节点的前驱和后继都指向自己。

    另外所有的构造函数无外乎都都是调用fill_initialize与range_initialize

     void fill_initialize(size_type n, const T& value) {
        empty_initialize();
        __STL_TRY {
          insert(begin(), n, value);
        }
        __STL_UNWIND(clear(); put_node(node));
      }
    
    #ifdef __STL_MEMBER_TEMPLATES
      template <class InputIterator>
      void range_initialize(InputIterator first, InputIterator last) {
        empty_initialize();
        __STL_TRY {
          insert(begin(), first, last);
        }
        __STL_UNWIND(clear(); put_node(node));
      }
    #else  /* __STL_MEMBER_TEMPLATES */
      void range_initialize(const T* first, const T* last) {
        empty_initialize();
        __STL_TRY {
          insert(begin(), first, last);
        }
        __STL_UNWIND(clear(); put_node(node));
      }
      void range_initialize(const_iterator first, const_iterator last) {
        empty_initialize();
        __STL_TRY {
          insert(begin(), first, last);
        }
        __STL_UNWIND(clear(); put_node(node));
      }
    #endif /* __STL_MEMBER_TEMPLATES */

    可以看出,除了默认构造函数外的所有的构造函数都最终调用insert函数来插入初始化,insert有多重重载方式。

     

    除特别注明外,本站所有文章均为String me = "Creater\忠实的资深Linux玩家";原创,转载请注明出处来自http://unix8.net/home.php/908.html

    关于

    发表评论

    暂无评论

    切换注册

    登录

    忘记密码 ?

    切换登录

    注册

    扫一扫二维码分享