六一的部落格


关关难过关关过,前路漫漫亦灿灿。




创建allocator对象

默认初始化

1allocator<T> a;

申请整块动态内存, 足以容纳指定个数的元素

allocate

  1. 动态内存是原始的、未构造的
  2. 返回值为指向这片动态空间的内置指针
  3. 需另外保存指针和对象个数
1T *p = a.allocate(n);

有序构造动态对象

construct

使用args在p指向的原始动态内存构造动态对象

1a.construct(p, args);

逆序析构动态对象

destroy

对p指向的动态对象调用析构函数

1a.destroy(p);

归还整块动态内存

deallocate

用到申请整块动态内存后保存的指针和对象个数:

  • p为allocate的返回值
  • n为传给allocate的动态对象个数

p、n不具有灵活性

调用deallocate之前,保证对象已被析构

1a.deallocate(p, n);

示例

 1allocator<string> alloc;
 2auto n = 10;
 3auto start = alloc.allocate(n), cur = start; // 申请动态内存; 保存start,调用deallocate时使用;cur指向未构造对象
 4
 5                                             // 有序构造动态对象
 6alloc.construct(cur++);                      // 空串
 7alloc.construct(cur++, 10, 'c');             // 10个'c'
 8alloc.construct(cur++, "hi");                // "hi"
 9
10while (cur != start)
11    alloc.destroy(--cur);                    // 逆序析构动态对象
12
13alloc.deallocate(start, n);                  // 归还动态内存空间

使用泛型算法初始化allocator管理的动态内存

输入序列有两种:

  1. 接受迭代器范围表示的输入序列

    [b, e]

  2. 给出指向输入序列首元素的迭代器和输入序列元素个数

    [b, b + n)


使用输入序列构造动态对象

cur为输入迭代器, 指向待构造对象

默认allocator管理的动态内存足够容纳待构造元素

返回指向待构造对象的内置指针

1uninitialized_copy(b, e, cur);
2
3uninitialized_copy_n(b, n, cur);

将输入序列中的元素构造为给定对象的拷贝

t为给定对象; 将输入序列中的每一个元素构造为给定对象的拷贝

默认输入序列有效

  1. 返回void
    1uninitialized_fill(b, e, t);
  2. 返回内置指针 b + n
    1uninitialized_fill_n(b, n, t);

示例

 1#include <iostream>
 2#include <vector>
 3#include <memory>
 4
 5void Print_Allocator_Int(int *b, int *e) {
 6    for (auto i = b; i != e; i++)
 7        std:: cout << *i << " ";
 8    std::cout << std::endl;
 9}
10
11int main() {
12    std::vector<int> ivec{0, 1, 2, 3, 4, 5};
13    std::vector<int> ivec2{10, 11, 12, 13, 14, 15};
14
15    std::allocator<int> alloc;
16    auto begin = alloc.allocate(ivec.size() * 5), cur = begin;
17
18    alloc.construct(cur++, 100);
19    // 构造1个元素, 100
20
21    cur = std::uninitialized_copy(ivec.begin(), ivec.end(), cur);
22    // 构造6个元素, 0, 1, 2, 3, 4, 5
23
24    cur = std::uninitialized_copy_n(ivec2.begin(), 6, cur);
25    // 构造6个元素, 10, 11, 12, 13, 14, 15
26
27    std::uninitialized_fill(cur, cur + 5, 99);
28    cur += 5;
29    // 构造5个元素: 99, 99, 99, 99, 99
30
31    cur = std::uninitialized_fill_n(cur, 5, 100);
32    // 构造5个元素: 100, 100, 100, 100, 100
33
34    Print_Allocator_Int(begin, cur);
35
36    return 0;
37}

输出

100 0 1 2 3 4 5 10 11 12 13 14 15 99 99 99 99 99 100 100 100 100 100

使用allocator分离动态内存申请和对象构造



创建allocator对象

默认初始化

1allocator<T> a;

申请整块动态内存, 足以容纳指定个数的元素

allocate

  1. 动态内存是原始的、未构造的
  2. 返回值为指向这片动态空间的内置指针
  3. 需另外保存指针和对象个数
1T *p = a.allocate(n);

有序构造动态对象

construct

使用args在p指向的原始动态内存构造动态对象

1a.construct(p, args);

逆序析构动态对象

destroy

对p指向的动态对象调用析构函数

1a.destroy(p);

归还整块动态内存

deallocate

用到申请整块动态内存后保存的指针和对象个数:

  • p为allocate的返回值
  • n为传给allocate的动态对象个数

p、n不具有灵活性

调用deallocate之前,保证对象已被析构

1a.deallocate(p, n);

示例

 1allocator<string> alloc;
 2auto n = 10;
 3auto start = alloc.allocate(n), cur = start; // 申请动态内存; 保存start,调用deallocate时使用;cur指向未构造对象
 4
 5                                             // 有序构造动态对象
 6alloc.construct(cur++);                      // 空串
 7alloc.construct(cur++, 10, 'c');             // 10个'c'
 8alloc.construct(cur++, "hi");                // "hi"
 9
10while (cur != start)
11    alloc.destroy(--cur);                    // 逆序析构动态对象
12
13alloc.deallocate(start, n);                  // 归还动态内存空间

使用泛型算法初始化allocator管理的动态内存

输入序列有两种:

  1. 接受迭代器范围表示的输入序列

    [b, e]

  2. 给出指向输入序列首元素的迭代器和输入序列元素个数

    [b, b + n)


使用输入序列构造动态对象

cur为输入迭代器, 指向待构造对象

默认allocator管理的动态内存足够容纳待构造元素

返回指向待构造对象的内置指针

1uninitialized_copy(b, e, cur);
2
3uninitialized_copy_n(b, n, cur);

将输入序列中的元素构造为给定对象的拷贝

t为给定对象; 将输入序列中的每一个元素构造为给定对象的拷贝

默认输入序列有效

  1. 返回void
    1uninitialized_fill(b, e, t);
  2. 返回内置指针 b + n
    1uninitialized_fill_n(b, n, t);

示例

 1#include <iostream>
 2#include <vector>
 3#include <memory>
 4
 5void Print_Allocator_Int(int *b, int *e) {
 6    for (auto i = b; i != e; i++)
 7        std:: cout << *i << " ";
 8    std::cout << std::endl;
 9}
10
11int main() {
12    std::vector<int> ivec{0, 1, 2, 3, 4, 5};
13    std::vector<int> ivec2{10, 11, 12, 13, 14, 15};
14
15    std::allocator<int> alloc;
16    auto begin = alloc.allocate(ivec.size() * 5), cur = begin;
17
18    alloc.construct(cur++, 100);
19    // 构造1个元素, 100
20
21    cur = std::uninitialized_copy(ivec.begin(), ivec.end(), cur);
22    // 构造6个元素, 0, 1, 2, 3, 4, 5
23
24    cur = std::uninitialized_copy_n(ivec2.begin(), 6, cur);
25    // 构造6个元素, 10, 11, 12, 13, 14, 15
26
27    std::uninitialized_fill(cur, cur + 5, 99);
28    cur += 5;
29    // 构造5个元素: 99, 99, 99, 99, 99
30
31    cur = std::uninitialized_fill_n(cur, 5, 100);
32    // 构造5个元素: 100, 100, 100, 100, 100
33
34    Print_Allocator_Int(begin, cur);
35
36    return 0;
37}

输出

100 0 1 2 3 4 5 10 11 12 13 14 15 99 99 99 99 99 100 100 100 100 100