标准库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个标 ...
随机推荐
- 模拟Json格式传值请求与数据接收
a.php代码: function http_post_json($url, $jsonStr) { $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, ...
- Windows下MySQL安装配置与使用
1.下载. 下载地址: http://downloads.mysql.com/archives/get/file/mysql-5.7.11-winx64.zip. NavicatforMySQL:ht ...
- WireShark:TCP三次握手 抓包
本机ip:192.168.201.200 服务器ip:192.168.230.20 抓到的数据如下: 第一次握手: SYN标记位为1,表示这是一个连接请求.seq 用于服务端返回确认信息,此时ack ...
- 结构型设计模式之代理模式(Proxy)
结构 意图 为其他对象提供一种代理以控制对这个对象的访问. 适用性 在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用P r o x y 模式.下面是一 些可以使用P r o x y 模式常见 ...
- 无线网络发射器选址 (NOIP2014)(真·纯模拟)
原题传送门 好吧,如果说D1T1是纯模拟大水题 D2T1就是纯模拟略水题. 这道题首先我们要看一看数据范围.. 0<=n,m<=128 送分也不带这么送的吧.. 二维前缀和,前缀和,二次循 ...
- ES6 - Babel编译环境搭建
都看到这里了,我就不写什么node环境安装之类的了. 直接从新建项目文件夹后开始吧! 安装依赖: 命令行cd到项目文件夹之后,执行以下命令:(mac记得前边加sudo) npm init –y // ...
- APscheduler总结
APscheduler使用总结 APscheduler是执行定时任务的python库,其作用可以代替Linux系统下的crontab,github上有该库的例子. APsheduler基本使用 该模块 ...
- Netty源码学习(五)ChannelInitializer
0. ChannelInitializer简介 直接用ChannelInitializer的注释吧:A special ChannelInboundHandler which offers an ea ...
- 线段树【p2629】 好消息,坏消息
顾z 你没有发现两个字里的blog都不一样嘛 qwq 题目描述-->p2629 好消息,坏消息 历程 刚开始看到这个题,发现是需要维护区间和,满心欢喜敲了一通线段树,简单debug之后交上去 \ ...
- ELK集群
kafka集群-------------------1. 下载wget http://mirror.rise.ph/apache/kafka/0.11.0.0/kafka_2.12-0.11.0.0. ...