标准库Allocator的使用(一)
上一篇我们提到了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的使用(一)的更多相关文章
- 标准库Allocator的简易实现(二)
自己实现Allocator并不难,其实只需要改变allocate和deallocate,来实现自己的内存分配策略. 下面是一个std::allocator的模拟实现 #ifndef ALLOCAT ...
- 标准库Allocator(三)uninitialized_fill等函数的实现
前面我们使用了uninitialized_fill,来批量初始化某一段内存. 下面提供三个函数的实现代码,这三个代码的共同点是: 1.遇到错误,抛出异常 2.出现异常时,把之前构造的对象全部销毁 所以 ...
- 把《c++ primer》读薄(3-1 标准库string类型初探)
督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. 问题1:养成一个好习惯,在头文件中只定义确实需要的东西 using namespace std; //建议需要什么再using声 ...
- 《C++ Primer》学习笔记【第二部分 C++标准库】
第8章 IO库 IO对象不能复制,即1.IO对象不能存储在vector或其他容器中 2.如果需要传递或返回IO对象,必须传递或返回指向该对象的指针或引用. 一般情况下,如果要传递IO对象以便对它进 ...
- 【转】C++标准库和标准模板库
C++强大的功能来源于其丰富的类库及库函数资源.C++标准库的内容总共在50个标准头文件中定义.在C++开发中,要尽可能地利用标准库完成.这样做的直接好处包括:(1)成本:已经作为标准提供,何苦再花费 ...
- C++标准库<string>简单总结
C++标准库<string>简单总结 在C++中,如果需要对字符串进行处理,那么它自带的标准库<string>无疑是最好的选择,它实现了很多常用的字符处理函数. 要想使用标准C ...
- C++标准库和标准模板库
转自原文http://blog.csdn.net/sxhelijian/article/details/7552499 C++强大的功能来源于其丰富的类库及库函数资源.C++标准库的内容总共在50个标 ...
- [技术] OIer的C++标准库 : 字符串库<string>
引入 上次我在博客里介绍了OI中可能用到的STL中的功能, 今天我们接着来发掘C++标准库中能为OI所用的部分. 众所周知, OI中经常用到字符串相关的处理, 这时善用字符串库可以使一些操作更加简洁易 ...
- C++标准库和标准模板库(转)
转自原文http://blog.csdn.net/sxhelijian/article/details/7552499 C++强大的功能来源于其丰富的类库及库函数资源.C++标准库的内容总共在50个标 ...
随机推荐
- redis 的命令总结
此博客为技术收集和个人的学习积累,如侵犯了您的权益,请联系我,我会及时删除,谢谢 [Redis] redis-cli 命令总结 Redis提供了丰富的命令(command)对数据库和各种数据类型进行操 ...
- 信息传递(NOIP2015)(寻找最小环。。)
原题传送门 这是一道寻找最小环的题目. 在做的时候给每一个点染色.. 防止再做已经搜过的点(优化) v[]表示是否访问的过,以及第一次访问该点的时间. u[]表示染色.. 这道题还可以用拓补排序做. ...
- I2C总线介绍
1. 简介 I2C, Inter-Integrated Circuit, 是一种串行通信总线,用于连接微控制器及其外围设备它是一种两线式串行总线(串行数据:SDA; 串行时钟频率:SCL), 利用电阻 ...
- Python的程序结构[1] -> 方法/Method[3] -> 魔术方法 __getattr__ 与代理模式
__getattr__ 方法 __getattr__ 方法当对象调用内部属性(包括方法等)且未找到对应属性的时候会调用的特殊方法.利用这一特性,可是对函数实现一个代理模式. __getattr__方法 ...
- 由"软件是干什么的"引发的思考
自工作以来,都只在进行模块的开发,很少站在整个项目的角度思考过.甚至,自己开发的软件,自己都没有去用过,包括开发的一些APP,都没有下载来认真体验过.思考过.却对自己手机上那些用过的A ...
- 状压DP【p1896】[SCOI2005]互不侵犯
Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包 ...
- [BZOJ3237][AHOI2013]连通图(分治并查集)
3237: [Ahoi2013]连通图 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1736 Solved: 655[Submit][Status ...
- 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 ...
- Delphi ParamStr 使用方法
ParamStr(0) 代表程序的路径, ParamStr(1) 代表程序的设置的参数
- Facebook KeyHash生成方法
1. 去https://code.google.com/p/openssl-for-windows/downloads/list下载OpenSSL工具 2. 在C盘根目录下新建一个openssl的文 ...