上一篇我们提到了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. 洛谷P3144 [USACO16OPEN]关闭农场Closing the Farm

    农夫约翰和他的奶牛准备去旅行,所以约翰想要把他的农场临时关闭. 农场有N个牛棚(牛棚从1到N编号),有M条路连接这些牛棚(1≤N,M≤3000). 约翰打算挨个关闭牛棚,在关牛棚的时候, 他突然想起一 ...

  2. python 使用urllib2下载文件

    #! usr/bin/python #coding=utf-8 import urllib2 fp = open('test', 'wb') req = urllib2.urlopen('http:/ ...

  3. Xcode5 上64位编译 出错No architectures to compile for

    http://blog.csdn.net/chocolateloveme/article/details/16900999 详细错误信息如下: No architectures to compile ...

  4. 和菜鸟一起学c之gcc编译过程及其常用编译选项【转】

    转自:http://blog.csdn.net/eastmoon502136/article/details/8162626 版权声明:本文为博主东月之神原创文章,未经博主允许不得转载. 上篇文章,知 ...

  5. Selenium2+python自动化30-引入unittest框架【转载】

    本篇转自博客:上海-悠悠 原文地址:http://www.cnblogs.com/yoyoketang/tag/unittest/ from selenium import webdriverfrom ...

  6. html5进阶之canvas图像基础

    1.首先还是使用之前讲过的Image()函数来预加载图像. 在调用图像之前,需创建一个事件监听器,为其保证图像已经正确的加载. 如下图: 监听图片已经正确加载 2.把图像显示在画布上面,这里将不再使用 ...

  7. ARC 098 D - Xor Sum 2

    Problem Statement There is an integer sequence A of length N. Find the number of the pairs of intege ...

  8. u-boot-2010.3移植到Tiny6410问题总结

    问题1: u-boot-2010.3中nand_spl文件夹的作用:实现从Nandflash启动在编译是会建立几个链接文件,用这几个链接文件生成u-boot-spl-16k.bin nand_spl/ ...

  9. centos iptables关于ping

    配置iptables策略后,一般来说INPUT都是DROP然后配置需要通过的 当执行: iptables -P INPUT DROP 后,机器就不能被ping通了! 因为icmp没有添加到规则中! 于 ...

  10. centos查找文件

    centos查找文件 [root@localhost ~]# find / -name libmysqlclient.so