上一篇我们提到了new运算符以及它的工作步骤,其实无非是把两项工作独立出来:

1.申请原始内存

2.执行构造函数

delete也涉及了两个工作:

1.执行析构函数

2.释放原始内存

其实标准库提供了另外一种更加高级的手段实现内存的分配和构造,就是std::allocator<T>的职责。

allocator提供了四个操作:

a.allocate(num) 为num个元素分配内存

b.construct(p) 将p所指的元素初始化

destroy(p) 销毁p指向的元素

deallocate(p, num) 回收p指向的“可容纳num个元素”的内存空间

使用示例如下:

#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std; class Test
{
public:
Test() { cout << "Test" << endl; }
~Test() { cout << "Test ..." << endl; } Test(const Test &t)
{
cout << "Copy ....." << endl;
} private:
//Test(const Test &);
//void operator(const Test &);
}; int main(int argc, const char *argv[])
{
allocator<Test> alloc;
Test *pt = alloc.allocate(); //申请三个单位的Test内存
//此时pt指向的是原始内存
{
alloc.construct(pt, Test()); //构建一个对象,使用默认值
//调用的是拷贝构造函数
alloc.construct(pt+, Test());
alloc.construct(pt+, Test());
}
alloc.destroy(pt);
alloc.destroy(pt+);
alloc.destroy(pt+); alloc.deallocate(pt, );
return ;
}

这里注意,allocator提供的allocate函数与operator new函数区别在于返回值,所以前者更加安全。

还有一点,construct一次只能构造一个对象,而且调用的是拷贝构造函数

标准库提供了三个算法用于批量构造对象(前提是已经分配内存)

uninitialized_fill(beg, end, val)   //以val初始化[beg,end)
uninitialized_fill_n(beg, num, val) //以val初始化beg开始的num个元素
uninitialized_copy(beg, end, mem) //以[beg, end)的各个元素初始化mem开始的各个元素

以上三个函数操控的对象都是原始内存示例如下:

#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <stdlib.h>
using namespace std; class Test
{
public:
Test(int val) :val_(val) { cout << "Test" << endl; } ~Test() { cout << "Test ..." << endl; } Test(const Test &t)
:val_(t.val_)
{
cout << "Copy ....." << endl;
} int val_;
}; int main(int argc, const char *argv[])
{ Test *pt = (Test *)malloc( * sizeof (Test)); Test t(); uninitialized_fill(pt, pt + , t);
cout << pt[].val_ << endl; Test *pt2 = (Test *)malloc( * sizeof (Test));
uninitialized_copy(pt, pt + , pt2); free(pt);
free(pt2);
return ;
}

这里注意标准库的copy、fill函数与uninitialized_系列函数的区别:

copy、fill等操作的是已经初始化对象的内存,因此调用的是赋值运算符

而uninitialized_针对的是原始内存,调用的是拷贝构造函数

OK,我们到此,可以总结出分配原始内存的三种手段:

1.使用malloc

2.使用operator new

3.allocator的allocate函数

这三者从上到下,是一个由低级到高级的过程。

那么执行构造函数,有两种手段:

1.使用placement new运算符

2.使用allocator的construct函数

最后,C语言中的数据都是POD类型,使用原始内存即可,但是C++中的大部分都是非POD类型,需要执行相应的初始化函数,所以,在C++中应该尽可能避免使用memcpy之类的直接操控原始内存的函数

标准库Allocator的使用(一)的更多相关文章

  1. 标准库Allocator的简易实现(二)

    自己实现Allocator并不难,其实只需要改变allocate和deallocate,来实现自己的内存分配策略.   下面是一个std::allocator的模拟实现 #ifndef ALLOCAT ...

  2. 标准库Allocator(三)uninitialized_fill等函数的实现

    前面我们使用了uninitialized_fill,来批量初始化某一段内存. 下面提供三个函数的实现代码,这三个代码的共同点是: 1.遇到错误,抛出异常 2.出现异常时,把之前构造的对象全部销毁 所以 ...

  3. 把《c++ primer》读薄(3-1 标准库string类型初探)

    督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. 问题1:养成一个好习惯,在头文件中只定义确实需要的东西 using namespace std; //建议需要什么再using声 ...

  4. 《C++ Primer》学习笔记【第二部分 C++标准库】

    第8章 IO库 IO对象不能复制,即1.IO对象不能存储在vector或其他容器中   2.如果需要传递或返回IO对象,必须传递或返回指向该对象的指针或引用. 一般情况下,如果要传递IO对象以便对它进 ...

  5. 【转】C++标准库和标准模板库

    C++强大的功能来源于其丰富的类库及库函数资源.C++标准库的内容总共在50个标准头文件中定义.在C++开发中,要尽可能地利用标准库完成.这样做的直接好处包括:(1)成本:已经作为标准提供,何苦再花费 ...

  6. C++标准库<string>简单总结

    C++标准库<string>简单总结 在C++中,如果需要对字符串进行处理,那么它自带的标准库<string>无疑是最好的选择,它实现了很多常用的字符处理函数. 要想使用标准C ...

  7. C++标准库和标准模板库

    转自原文http://blog.csdn.net/sxhelijian/article/details/7552499 C++强大的功能来源于其丰富的类库及库函数资源.C++标准库的内容总共在50个标 ...

  8. [技术] OIer的C++标准库 : 字符串库<string>

    引入 上次我在博客里介绍了OI中可能用到的STL中的功能, 今天我们接着来发掘C++标准库中能为OI所用的部分. 众所周知, OI中经常用到字符串相关的处理, 这时善用字符串库可以使一些操作更加简洁易 ...

  9. C++标准库和标准模板库(转)

    转自原文http://blog.csdn.net/sxhelijian/article/details/7552499 C++强大的功能来源于其丰富的类库及库函数资源.C++标准库的内容总共在50个标 ...

随机推荐

  1. redis 的命令总结

    此博客为技术收集和个人的学习积累,如侵犯了您的权益,请联系我,我会及时删除,谢谢 [Redis] redis-cli 命令总结 Redis提供了丰富的命令(command)对数据库和各种数据类型进行操 ...

  2. 信息传递(NOIP2015)(寻找最小环。。)

    原题传送门 这是一道寻找最小环的题目. 在做的时候给每一个点染色.. 防止再做已经搜过的点(优化) v[]表示是否访问的过,以及第一次访问该点的时间. u[]表示染色.. 这道题还可以用拓补排序做. ...

  3. I2C总线介绍

    1. 简介 I2C, Inter-Integrated Circuit, 是一种串行通信总线,用于连接微控制器及其外围设备它是一种两线式串行总线(串行数据:SDA; 串行时钟频率:SCL), 利用电阻 ...

  4. Python的程序结构[1] -> 方法/Method[3] -> 魔术方法 __getattr__ 与代理模式

    __getattr__ 方法 __getattr__ 方法当对象调用内部属性(包括方法等)且未找到对应属性的时候会调用的特殊方法.利用这一特性,可是对函数实现一个代理模式. __getattr__方法 ...

  5. 由"软件是干什么的"引发的思考

            自工作以来,都只在进行模块的开发,很少站在整个项目的角度思考过.甚至,自己开发的软件,自己都没有去用过,包括开发的一些APP,都没有下载来认真体验过.思考过.却对自己手机上那些用过的A ...

  6. 状压DP【p1896】[SCOI2005]互不侵犯

    Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包 ...

  7. [BZOJ3237][AHOI2013]连通图(分治并查集)

    3237: [Ahoi2013]连通图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1736  Solved: 655[Submit][Status ...

  8. Codeforces 908 D New Year and Arbitrary Arrangement

    Discription You are given three integers k, pa and pb. You will construct a sequence with the follow ...

  9. Delphi ParamStr 使用方法

    ParamStr(0) 代表程序的路径, ParamStr(1) 代表程序的设置的参数

  10. Facebook KeyHash生成方法

    1. 去https://code.google.com/p/openssl-for-windows/downloads/list下载OpenSSL工具 2.  在C盘根目录下新建一个openssl的文 ...