C++Primer : 第十二章 :allocator类

当分配一大块内存时,我们通过计划在这块内存上按需求构造对象。在此情况下,我们希望将内存分配和对象构造分离。这意味着我们可以分配大块内存,但是真正需要时才真正执行对象创建操作。
标准库allocator类定义在头文件memory中,它将内存分配和对象构造分开

allocator<string> alloc;     //可以分配string的allocator对象
auto const p = alloc.allocate(n);    //分配n个未初始化的string

标准库allocator类以及算法

allocator<T> a      //定义了一个名为a的allocator对象,它可以为类型为T的对象分配内存
a.allocate(n)       //分配一段原始的、未构造的内存,保存n个类型为T的对象
a.deallocate(p, n)  //释放从T*指针p中地址开始的内存,这块内存保存了n个类型为T的对象,调用deallocate前,用户必须对每个在这块内存中创建的对象调用destroy
a.construct(p, args) //args被传递给类型为T的构造函数,用来在p指向的内存中构造一个对象
a.destory(p)         //p为T*类型的指针,此算法对p指向的对象执行析构函数

allocator分配未构造的内存
allocator分配的内存是未构造的(unconstructed),我们按需要在此内存中构造对象。

auto q = p;     //q指向最后构造的元素之后的位置
alloc.construct(q++);   // *q为空字符串
alloc.construct(q++, "hi");    //*q为hi

为了使用allocate返回的内存,我们必须使用construct构造对象。使用未构造的内存,其行为是未定义的
当我们用完对象后,必须对每个构造的元素调用destory来销毁它们。函数destory接受一个指针,对指向的对象执行析构函数

while (q != p){
	alloc.destory(--q);    //释放我们真正构造的string
}

在循环开始处,q指向最后构造的元素之后的位置,最后一步循环中我们destory了第一个构造的元素,随后q将与p相等,循环结束。
一旦元素被销毁后,可以使用这部分内存来保存其他string,也可以将其归还给系统

alloc.deallocate(p, n);

我们传递给deallocate的指针不能为空,它必须指向由allocate分配的内存。而且,传递给deallocate的大小参数必须与调用allocate分配内存时提供的大小参数具有一样的值

拷贝和填充未初始化内存的算法
标准库还为allocator类定义了两个伴随算法,可以在未初始化内存中创建对象,定义在memory头文件中。
allocator算法

uninitialized_copy(b, e, b2)   //从迭代器b和e指出的输入范围中拷贝元素到迭代器b2指定的未构造的原始内存中
uninitialized_copy_n(b, n, b2) //从迭代器b指向的元素开始,拷贝n个元素到b2开始的内存中
uninitialized_fill(b, e, t)    //在迭代器b和e指定的原始内存范围中创建对象,对象的值均为t的拷贝
uninitialized_fill_n(b, n, t)  //从迭代器b指向的内存地址开始创建n个对象
//分配比vi中元素所占空间大一倍的动态内存
auto p = alloc.allocate(vi.size()*2);
//通过拷贝vi中的元素来构造从p开始的元素
auto q = uninitialized_copy(vi.begin(), vi.end(), p);
//将剩余元素初始化为42
uninitialized_fill_n(q, vi.size(), 42);

一次uninitialized_copy调用会返回一个指针,指向最后一个构造的元素之后的位置

#include <iostream>
#include <string>
#include <memory>
using namespace std;
int main() {
	allocator<string> alloc;
	auto const p = alloc.allocate(100);      //分配100个未初始化的string
	string s;
	string* q = p;     //q指向第一个string
	while (cin >> s && q != p + 100)
		alloc.construct(q++, s);       //用s初始化*q
	const size_t size = q - p;         //记住读取了多少个string
	for (size_t i = 0; i < size; i++) {
		cout << p[i] << " " << endl;
	}
	while (q != p)      //使用完毕后释放已构造的string
		alloc.destroy(--q);
	alloc.deallocate(p, 100);     //释放内存
	return 0;
}
发布了73 篇原创文章 · 获赞 4 · 访问量 1684

猜你喜欢

转载自blog.csdn.net/CLZHIT/article/details/104049313