动态存储类

StrVec Class Design

StrVec Class Definition

class StrVec
{
public:
//构造函数
StrVec():elements(nullptr), first_free(nullptr), cap(nullptr){} //用initializer_list<string>初始化參数列表
StrVec(initializer_list<string> il):StrVec(il){} //拷贝构造函数
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;} //第一个为空的元素
//。。 。 private:
// vector<string> vs;
allocator<string> alloc; //分配元素
//推断是否要加入新的内存空间
void chk_n_alloc()
{
if(size() == capacity()) //推断数据长度是否已经达到分配空间的上限
reallocate(); //假设是,那么就又一次分配空间
}
//用到拷贝构造函数,拷贝赋值运算符,析构函数的工具函数
pair<string*, string*> alloc_n_copy(const string*, const string*);
void free(); //销毁这个类的元素,并释放空间
void reallocate(); //又一次分配空间而且把原来的元素移动到新空间上 string *elements; //指向这个队列的第一个元素
string *first_free; //指向这个队列第一个为空的元素,即最后元素的后一位
string *cap; //指向最后一个空间位置后一位
};

English explain:

• The default constructor (implicitly) default initializes alloc and (explicitly)

initializes the pointers to nullptr, indicating that there are no elements.

• The size member returns the number of elements actually in use, which is

equal to first_free - elements.

• The capacity member returns the number of elements that the StrVec can

hold, which is equal to cap - elements.

• The chk_n_alloc causes the StrVec to be reallocated when there is no room

to add another element, which happens when cap == first_free.

• The begin and end members return pointers to the first (i.e., elements) and

one past the last constructed element (i.e., first_free), respectively.

Using construct

void StrVec::push_back(const string& s)
{
chk_n_alloc(); //检查看是否须要又一次分配空间
//吧元素s复制到first_free之后
alloc.construct(first_free++, s); //一个空间就是一个string大小
}

The alloc_n_copy Member

拷贝构造函数。拷贝赋值运算符,析构函数的工具函数

inline
pair<string*, string*>
StrVec::alloc_n_copy(const string* b, const string* e) //開始和结尾指针
{
//要拷贝对象要求的空间大小
auto data=alloc.allocate(e-b);
//吧b,e之间的元素复制到data中
//返回一个pair
pair<string*, string*> p={data, uninitialized_copy(b, e, data)};
return p;
}

The free Member

void StrVec::free()
{
//假设头指针本身就是空的,那么就不用释放内存了,由于就是空的
if(elements)
{
//倒序,一个个的吧元素删除,内存释放
for(auto p=first_free ; p != elements ; /* empty )
alloc.destroy(--p);
alloc.deallocate(elements, cap-elements);
/*
deallocate(p,n); 释放内存。
在类型为T*的指针p指向的地址,保存着n个对象。
执行deallocate之前调用destroy是用户的责任。 Once the elements have been destroyed, we free the space that this StrVec
allocated by calling deallocate */
    }
}

这里有一个错误演示。我也还没搞懂为什么报错,调了半天没出来,仅仅要留在这里,以后攻克了。

void StrVec::free()
{
if(elements)
{
for_each(first_free, elements, [this](string* p){alloc.destroy(--p);});
alloc.deallocate(elements, cap-first_free);
}
}

2014年7月18日17:57:47

改正错误:
void StrVec::free()
{
if(elements)
{
for_each(first_free, elements, [this](string& p){alloc.destroy(&p);});
alloc.deallocate(elements, cap-first_free);
}
}

Copy-Control Members

StrVec::StrVec(const StrVec &s)
{
// call alloc_n_copy to allocate exactly as many elements as in s
auto newdata=alloc_n_copy(s.begin(), s.end()); //pair类型
elements=newdata.first;
first_free=cap=newdata.second;
//The return value from alloc_n_copy is a pair of pointers. }

The destructor calls free:

inline
StrVec::~StrVec()
{
free();
}

拷贝赋值运算符

StrVec &StrVec::operator=(const StrVec &rhs)
{
//先把要赋值的值拷贝下来
auto data=alloc_n_copy(rhs.begin(), rhs.end());
free(); //吧右边的值销毁
//又一次赋予给左边
elements=data.first;
first_free=cap=data.second; return *this;
}

Moving, Not Copying, Elements during Reallocation

move在头文件utility里面

The reallocate Member

void StrVec::reallocate()
{
//直接把当前容量扩充到2倍
auto newcapacity=size() ? 2*size() : 1 ;
//allocate新内存
auto newdata=alloc.allocate(newcapacity); //申请新空间
//吧元素重老的地方移到新的地方
auto dest=newdata; //指出新空间第一个空位置
auto elem=elements; //老队列的第一个元素
//所有构造到新的里面去
for(size_t i=0 ; i != size() ; ++i)
alloc.construct(dest++, std::move(*elem++)); //循环吧老的元素移动到新的上
free(); //移完了,把老空间所有释放 //又一次更新数据指针
elements=newdata;
first_free=dest;
cap=elements+newcapacity;
}

PS:不要问我。为什么你的英语突然变得那么厉害了!。。我是不会告诉你我的那本中文版的C++ primer被我搞掉了的!。。!

【足迹C++primer】46、动态存储类的更多相关文章

  1. C Primer Plus之存储类、链接和内存管理

    存储时期即生存周期——变量在内存中保留的时间 变量的作用域和链接一起表明程序的哪些部分可以通过变量名来使用该变量. 注意:生存期和作用域是两个不同的概念. 作用域    作用域描述了程序中可以访问一个 ...

  2. Kubernetes (1.6) 中的存储类及其动态供给

    原文地址:http://blog.fleeto.us/translation/dynamic-provisioning-and-storage-classes-kubernetes-0?utm_sou ...

  3. C Primer Plus--C存储类、链接和内存管理之存储类(storage class)

    目录 存储类 作用域 链接 存储时期 自动变量 寄存器变量 具有代码块作用域的静态变量 具有外部链接的静态变量 extern关键字 具有内部链接的静态变量 多文件 存储类 C为变量提供了5种不同的存储 ...

  4. C Primer Plus--C存储类、链接和内存管理之动态分配内存及类型限定词

    目录 存储类说明符 存储类和函数 动态分配内存 malloc函数 free函数 calloc函数 动态分配内存的缺点 C类型限定关键字 constant定义全局常量 volatile关键字 restr ...

  5. 【C语言学习笔记】存储类、链接和内存管理

    因为对内存管理部分一直没有很清楚的思路,所以一直在找资料想系统看一下这部分的内容.在C primer plus里看到了这一章,虽然大多都是心知肚明的东西,但是还是很多概念性系统性的东西让我眼前一亮,把 ...

  6. 秒懂C#通过Emit动态生成代码 C#使用Emit构造拦截器动态代理类

    秒懂C#通过Emit动态生成代码   首先需要声明一个程序集名称, 1 // specify a new assembly name 2 var assemblyName = new Assembly ...

  7. kubernetes 1.17.2 结合 Ceph 13.2.8 实现 静态 动态存储 并附带一个实验

    关于部署和相关原理 请自行搜索 这里 给出我的操作记录和排查问题的思路 这一节对后面的学习有巨大的作用!!! [root@bs-k8s-ceph ~]# ceph -s cluster: -1a9a- ...

  8. C++ Primer Plus 学习之 类继承

    主要介绍了类的继承.虚函数.类继承的动态内存分配问题.继承与友元函数. 公有派生 基类的公有成员和私有成员都会成为派生类的一部分. 基类的私有成员只能通过基类的公有或者保护方法访问.但是,基类指针或引 ...

  9. SQLite存储类(数据类型)

    SQLite数据类型更普遍,采用动态类型系统. 说是数据类型,更像是存储类,如:INTEGER存储类就包含多种不同长度的整数数据类型 [INTEGER]带符号的整数类型 [REAL]浮点值,小数类型 ...

随机推荐

  1. freemarker常用的基本命令

    freemarker包括下面几个基本命令 if,else,elseif指令switch,case,default,break指令list,break指令include指令import 指令nopars ...

  2. 配置 VS 2015 开发跨平台手机应用

    为了使用 VS 2015 开发跨平台手机应用,VS 2015 装了很多次,遇到了很多坑,才终于弄明白怎样配置才能正常使用C#开发手机应用,现把步骤分享给大家,以免大家少走弯路. 运行环境: Windo ...

  3. 对于数据操作的SQL语句精粹(长期更新)

    --删除空格 Update [Table] Set [Column]=Replace([Column],' ','') --查出左右和右边带空格的数据 select RTRIM( LTRIM([Col ...

  4. Linq/List/Array/IEnumerable等集合操作

    来源:http://www.cnblogs.com/liushanshan/archive/2011/01/05/1926263.html 目录 1    LINQ查询结果集    1 2    Sy ...

  5. out返回值的用法与用途

    static void Main(string[] arr) { Console.WriteLine("请输入用户名"); string uname = Console.ReadL ...

  6. ionic开发ios app

    注意必须是mac系统 1. 首先要安装node环境,Ionic的安装和后续的许多前端工具的安装都依赖于node的包管理器npm. nodeJs环境的安装很简单,去官网下载最新版的NodeJs直接安装即 ...

  7. js动态给table添加行(tr)

    html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> < ...

  8. 容器 MAP

    1.equal_range pair <myMapDef::iterator,myMapDef::iterator> myresult; myPairDef ps=*MyMap1.begi ...

  9. ARM 之LCD和LCD控制器

    既然提到 了LCD那么我们首先必须要了解的就是他的种类,CD(liquid crystal  display), 即液晶显示器,是这一种采用了液晶控制透光度计数来实现色彩的显示器,他与传统的CRT显示 ...

  10. Hibernate学习笔记-Hibernate HQL查询

    Session是持久层操作的基础,相当于JDBC中的Connection,通过Session会话来保存.更新.查找数据.session是Hibernate运作的中心,对象的生命周期.事务的管理.数据库 ...