• allocator类的使用


    allocator类是一个模板,它提供类型化的内存分配以及对象构造与撤销。allocator类将内存分配与对象构造分开。当allocator对象分配内存时,它分配适当大小并排列成保存给定类型对象的空间。但是,它分配的内存时未构造的,allocator用户必须分别construct和destroy放置在该内存中的对象。

    下面通过实现一个动态数组说明allocator的使用。

     1 #ifndef MYVECTOR_H
     2 #define MYVECTOR_H
     3 #include <memory>
     4 #include <cstddef>
     5 using namespace std;
     6 
     7 template <class T>
     8 class Vector
     9 {
    10 public:
    11     Vector(): elements(0), first_free(0), end(0) {}
    12     void push_back(const T&);
    13     void reserve(const size_t capa);
    14 
    15     //调整Vector大小,使其能容纳n个元素
    16     //如果n小于Vector当前大小,则删除多余元素
    17     //否则,添加采用值初始化的新元素
    18     void resize(const size_t n);
    19 
    20     //调整Vector大小,使其能容纳n个元素
    21     //所有新添加元素值都为t
    22     void resize(const size_t n, const T& t);
    23 
    24     //下表操作符
    25     T& operator[] (const size_t n);
    26     const T& operator[] (const size_t) const;
    27 
    28     //返回Vector大小
    29     size_t size()
    30     {
    31         return first_free-elements;
    32     }
    33 
    34     //返回Vector容量
    35     size_t capacity()
    36     {
    37         return end-elements;
    38     }
    39 
    40 private:
    41     //用于获取未构造内存的对象
    42     static std::allocator<T> alloc;
    43     //获取更多空间并复制现有元素
    44     void reallocate();
    45     
    46     //指向第一个元素的指针
    47     T* elements;
    48     //指向第一个自由元素的指针
    49     T* first_free;
    50     //指向数组末端的下一个元素位置的指针
    51     T* end;
    52 };
    53 
    54 #endif
      1 #include "Vector.hpp"
      2 
      3 template <class T>
      4 allocator<T> Vector<T>::alloc;
      5 
      6 template <class T>
      7 void Vector<T>::push_back(const T& t)
      8 {
      9     if (first_free == end)
     10         //已用完所分配空间
     11         //获取更多空间,并复制现有元素至新分配空间
     12         reallocate();
     13     alloc.construct(first_free, t);
     14     ++first_free;
     15 }
     16 
     17 template <class T>
     18 void Vector<T>::reallocate()
     19 {
     20     //计算当前大小,并分配两倍于当前元素数的空间
     21     ptrdiff_t size = first_free - elements;
     22     ptrdiff_t newcapacity = 2*max(size, 1);
     23 
     24     //分配空间以保存newcapacity个T类的元素
     25     T* newelements = alloc.allocate(newcapacity);
     26 
     27     //在新空间构造现有元素的副本
     28     uninitialized_copy(elements, first_free, newelements);
     29 
     30     //逆序撤销旧元素
     31     for (T *p = first_free; p != elements; )
     32         alloc.destroy(--p);
     33 
     34     //不能用0值指针调用deallocate
     35     if (elements)
     36         //释放保存元素的内存
     37         alloc.deallocate(elements, end-elements);
     38     
     39     //使数据结构指向新元素
     40     elements = newelements;
     41     first_free = elements + size;
     42     end = elements + newcapacity;
     43 }
     44 
     45 template <class T>
     46 void Vector<T>::reserve(const size_t capa)
     47 {
     48     //计算当前数组大小
     49     size_t size = first_free-elements;
     50     //分配可保存capa个T类型元素的空间
     51     T *newelements = alloc.allocate(capa);
     52     //在新空间构造现有元素的副本
     53     if (size <= capa)
     54         uninitialized_copy(elements, first_free, newelements);
     55     else
     56         //如果capa小于原来数组的size,则去掉多余的元素
     57         uninitialized_copy(elements, elements+capa, newelements);
     58 
     59     //逆序撤销旧元素
     60     for (T *p = first_free; p != elements; )
     61         alloc.destroy(--p);
     62 
     63     if (elements)
     64         //释放旧元素所占内存
     65         alloc.deallocate(elements, end-elements);
     66 
     67     //使数据结构指向新元素
     68     elements = newelements;
     69     first_free = elements + min(size, capa);
     70     end = elements + capa;
     71 }
     72 
     73 template <class T>
     74 void Vector<T>::resize(const size_t n)
     75 {
     76     //计算当前大小及容量
     77     size_t size = first_free - elements;
     78     size_t capacity = end - elements;
     79 
     80     if (n > capacity)
     81     {
     82         reallocate();
     83         uninitialized_fill(elements+size, elements+n, T());
     84     }
     85     else if (n > size)
     86     {
     87         uninitialized_fill(elements+size, elements+n, T());
     88     }
     89     else
     90     {
     91         for (T *p = first_free; p != elements; )
     92             alloc.destroy(--p);
     93     }
     94     first_free = elements + n;
     95 }
     96 
     97 template <class T>
     98 void Vector<T>::resize(const size_t n, const T& t)
     99 {
    100     size_t size = first_free - elements;
    101     size_t capacity = end - elements;
    102 
    103     if (n > capacity)
    104     {
    105         reallocate();
    106         uninitialized_fill(elements+size, elements+n, t);
    107     }
    108     else if (n > size)
    109     {
    110         uninitialized_fill(elements+size, elements+n, t);
    111     }
    112     else
    113     {
    114         for (T *p = first_free; p != elements; )
    115             alloc.destroy(--p);
    116     }
    117     first_free = elements+n;
    118 }
    119 
    120 template <class T>
    121 T& Vector<T>::operator[] (const size_t index)
    122 {
    123     return elements[index];
    124 }
    125 
    126 template <class T>
    127 const T& Vector<T>::operator[] (const size_t index) const
    128 {
    129     return elements[index];
    130 }
     1 #include <iostream>
     2 #include <string>
     3 #include "Vector.hpp"
     4 #include "Vector.cpp"
     5 using namespace std;
     6 
     7 
     8 int main()
     9 {
    10     Vector<int> ivec;
    11     for (size_t i = 0; i != 8; ++i)
    12     {
    13         ivec.push_back(i);
    14         cout << ivec[i] << "	";
    15     }
    16     cout << endl;
    17 
    18     cout << ivec.size() << "	" << ivec.capacity() << endl;
    19     ivec.reserve(50);
    20     cout << ivec.size() << "	" << ivec.capacity() << endl;
    21     ivec.resize(20);
    22     for (size_t i = 0; i != 20; ++i)
    23         cout << ivec[i] << "	";
    24     cout << endl;
    25 
    26     cout << ivec.size() << "	" << ivec.capacity() << endl;
    27     cout << ivec[2] << "	" << ivec[10] << endl;
    28 
    29 
    30     return 0;
    31 }
  • 相关阅读:
    MVC 4 中 WEB API 选择 返回格式
    用XML配置菜单的一种思路,附一些不太准确的测试代码
    2020.11.15(每周总结)
    2020.11.19
    2020.11.22
    2020.11.21
    2020.11.14
    202.11.13
    2020.11.20
    2020.11.17
  • 原文地址:https://www.cnblogs.com/bournet/p/4382089.html
Copyright © 2020-2023  润新知