13.39 编写自己的StrVec,包括自己版本的reserve、capacity和resize。

13.40 为StrVec添加一个构造函数,它接受一个initializer_list<string>参数

StrVec.h

#ifndef STRVEC_H
#define STRVEC_H
#include<iostream>
#include<string>
#include<utility>
#include<memory>
using namespace std;
class StrVec
{
public:
StrVec():elements(nullptr),first_free(nullptr),cap(nullptr){}
StrVec(const StrVec&);
StrVec& operator=(const StrVec&);
~StrVec();
void push_back(const string&);
size_t size() const { return first_free-elements;}
size_t capacity() const { return cap-elements;}
string *begin() const { return elements;}
string *end() const { return first_free;} void reserve(size_t n);
void resize(size_t n,string s=string()); StrVec(initializer_list<string> il)
{
auto newcapacity=il.size();
auto newdata=alloc.allocate(newcapacity);
auto dest=newdata;
auto elem=il.begin();
while(elem!=il.end())
alloc.construct(dest++,*elem);
elements=newdata;
first_free=cap=dest;
}
private:
static allocator<string> alloc;
string *elements;
string *first_free;
string *cap;
void chk_n_alloc()
{
if(size()==capacity()) reallocate();
}
pair<string*,string*> alloc_n_copy(const string*,const string*);
void free();
void reallocate();
};
#endif // STRVEC_H

StrVec.cpp

#include"StrVec.h"

allocator<string> StrVec::alloc;
StrVec::StrVec(const StrVec &s)
{
auto newdata=alloc_n_copy(s.begin(),s.end());
elements=newdata.first;
first_free=newdata.second;
cap=newdata.second;
} StrVec& StrVec::operator=(const StrVec &s)
{
auto data=alloc_n_copy(s.begin(),s.end());
free();
elements=data.first;
first_free=cap=data.second;
return *this;
} StrVec::~StrVec()
{
free();
} void StrVec::push_back(const string &s)
{
chk_n_alloc();
alloc.construct(first_free++,s);
} pair<string*,string*> StrVec::alloc_n_copy(const string *b, const string *e)
{
auto data=alloc.allocate(e-b);
return {data,uninitialized_copy(b,e,data)};
} void StrVec::free()
{
if(elements)
{
     //for_each(&first_free,&elements,[](string *p) { alloc.destroy(p);}); lambda式子
for(auto p=first_free;p!=elements;)
alloc.destroy(--p);
alloc.deallocate(elements,cap-elements);
}
} void StrVec::reallocate()
{
auto newcapacity=size()?*size():;
auto newdata=alloc.allocate(newcapacity);
auto dest=newdata;
auto elem=elements;
for(size_t i=;i!=size();++i)
alloc.construct(dest++,std::move(*elem++));
elements=newdata;
first_free=dest;
cap=elements+newcapacity;
} void StrVec::reserve(size_t n)
{
if(capacity()<n)
reallocate();
} void StrVec::resize(size_t n,string s)
{
if(size()<n)
push_back(s);
else if(size()>n)
{
for(auto p=elements+n;p!=first_free;)
alloc.destroy(p++);
first_free=elements+n;
}
}

allocator例子的更多相关文章

  1. new,delete和malloc,free以及allocator<T>

    一)new和delete,自己觉得一句话就是:最好同一作用域内,必须成对使用 先给出自己的认识: malloc,free,申请和释放一段heap堆中的内存. new:申请heap内存并在申请的内存中放 ...

  2. [转载] 彻底学习STL中的Allocator

    原文: http://cissco.iteye.com/blog/379093 帮助我们理解allocator的原理 Allocator是C++语言标准库中最神秘的部分之一.它们很少被显式使用,标准也 ...

  3. C++内存管理(超长,例子很详细,排版很好)

    [导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不 ...

  4. c/c++ allocator 使用

    allocator 使用 作用:只开辟空间,不调用构造函数 操作一览表 allocator<T> a 定义一个名为a的allocator对象,它可以为类型为T的对象分配内存 a.alloc ...

  5. C++ allocator

    C++ allocator http://www.cnblogs.com/wpcockroach/archive/2012/05/10/2493564.html 说一说C++里的allocator.我 ...

  6. allocator class

    当分配一大块内存时,我们通常计划在这块内存上按需构造对象,这样的我们希望将内存分配和对象构造分离.但是通常的new关键字的分配的动态空间,有时候会造成一些浪费,更致命的是“如果一个类没有默认构造函数, ...

  7. 动态数组& allocator

    问题来源 在编写程序的时候,对数组."二维数组"的分配的删除掌握的不是很清楚,不能正确的进行定义初始化. 以及在使用vector的时候,如何正确的定义及初始化 注意!!! 尽量使用 ...

  8. 浅谈C++ allocator内存管理(对比new的局限性)(转)

    STL中,对内存管理的alloc的设计,迫使我去学习了allocator类.这里对allocator内存管理做了点笔记留给自己后续查阅.allocator类声明.定义于头文件<memory> ...

  9. SQLServer地址搜索性能优化例子

    这是一个很久以前的例子,现在在整理资料时无意发现,就拿出来再改写分享. 1.需求 1.1 基本需求: 根据输入的地址关键字,搜索出完整的地址路径,耗时要控制在几十毫秒内. 1.2 数据库地址表结构和数 ...

随机推荐

  1. Dirichlet Process 和 Dirichlet Process Mixture模型

    Dirichlet Process 和 Dirichlet Process Mixture模型 [本文链接:http://www.cnblogs.com/breezedeus/archive/2012 ...

  2. 【技术贴】三星Note8 N5100实用教程,关闭相机快门声,增加浏览器退出按钮。

    需要root 增加快门声按钮: 在\system\csc\目录下,有个others.xml的手机功能定制文件,用root explorer之类可以修改系统文件权限的文本修改工具编辑它,在文件最末添加这 ...

  3. Ubuntu开机自动挂载Windows分区

    转自Ubuntu 12.04开机自动挂载Windows分区 1.查看系统磁盘号 sd2,sd5,sd7分别对应我windows的C,D,F盘,也是本次要添加到开机挂载的,E盘为wubi安装盘. 2.查 ...

  4. PYTHON---FILE IO

    import pickle shoplistfile = 'shoplist.data' shoplist = ['apple', 'mango', 'carrot'] f = open(shopli ...

  5. 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)

    [题目] Atlantis Problem Description There are several ancient Greek texts that contain descriptions of ...

  6. Web API路由与动作(三)

    本章包括三个小节  如果你输入了mvc的路由规则 这个可以粗略过一遍即可  内容说明有点繁琐 原文地址:http://www.asp.net/web-api/overview/web-api-rout ...

  7. 【Xamarin挖墙脚系列:在VMware11中安装Mac10.11 EI Captain后的vmware tools】

    原文:[Xamarin挖墙脚系列:在VMware11中安装Mac10.11 EI Captain后的vmware tools] 如何安装 darwin.iso,百度去吧. 关键是对应版本的darwin ...

  8. Linux守护进程daemon

      守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常常在系统引导装入时启 ...

  9. 代码演示C#中string和StingBuilder内存中的区别

    关于 string和StringBuilder的区别参考MSDN.本文用程序演示它们在内存中的区别,及其因此其行为不同. //Demo  string memory model namespace C ...

  10. GeoServer地图开发解决方案

    转自:http://www.cnblogs.com/beniao/archive/2011/01/08/1930822.html GeoServer 是 OpenGIS Web 服务器规范的 J2EE ...