【足迹C++primer】46、动态存储类
动态存储类
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; //指向最后一个空间位置后一位
};
• 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
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、动态存储类的更多相关文章
- C Primer Plus之存储类、链接和内存管理
存储时期即生存周期——变量在内存中保留的时间 变量的作用域和链接一起表明程序的哪些部分可以通过变量名来使用该变量. 注意:生存期和作用域是两个不同的概念. 作用域 作用域描述了程序中可以访问一个 ...
- Kubernetes (1.6) 中的存储类及其动态供给
原文地址:http://blog.fleeto.us/translation/dynamic-provisioning-and-storage-classes-kubernetes-0?utm_sou ...
- C Primer Plus--C存储类、链接和内存管理之存储类(storage class)
目录 存储类 作用域 链接 存储时期 自动变量 寄存器变量 具有代码块作用域的静态变量 具有外部链接的静态变量 extern关键字 具有内部链接的静态变量 多文件 存储类 C为变量提供了5种不同的存储 ...
- C Primer Plus--C存储类、链接和内存管理之动态分配内存及类型限定词
目录 存储类说明符 存储类和函数 动态分配内存 malloc函数 free函数 calloc函数 动态分配内存的缺点 C类型限定关键字 constant定义全局常量 volatile关键字 restr ...
- 【C语言学习笔记】存储类、链接和内存管理
因为对内存管理部分一直没有很清楚的思路,所以一直在找资料想系统看一下这部分的内容.在C primer plus里看到了这一章,虽然大多都是心知肚明的东西,但是还是很多概念性系统性的东西让我眼前一亮,把 ...
- 秒懂C#通过Emit动态生成代码 C#使用Emit构造拦截器动态代理类
秒懂C#通过Emit动态生成代码 首先需要声明一个程序集名称, 1 // specify a new assembly name 2 var assemblyName = new Assembly ...
- kubernetes 1.17.2 结合 Ceph 13.2.8 实现 静态 动态存储 并附带一个实验
关于部署和相关原理 请自行搜索 这里 给出我的操作记录和排查问题的思路 这一节对后面的学习有巨大的作用!!! [root@bs-k8s-ceph ~]# ceph -s cluster: -1a9a- ...
- C++ Primer Plus 学习之 类继承
主要介绍了类的继承.虚函数.类继承的动态内存分配问题.继承与友元函数. 公有派生 基类的公有成员和私有成员都会成为派生类的一部分. 基类的私有成员只能通过基类的公有或者保护方法访问.但是,基类指针或引 ...
- SQLite存储类(数据类型)
SQLite数据类型更普遍,采用动态类型系统. 说是数据类型,更像是存储类,如:INTEGER存储类就包含多种不同长度的整数数据类型 [INTEGER]带符号的整数类型 [REAL]浮点值,小数类型 ...
随机推荐
- WPF控件---Border应用
内容模型:Border 只能具有一个子元素.若要显示多个子元素, 需要将一个容器元素放置在父元素Border中. <Grid> <Border BorderBrush="B ...
- javascript正则
<script type="text/javascript"> //去除两边空格,如果要去除所有空格,使用/\s*即可/ String.prototype.trim ...
- WPF 获取屏幕分辨率(获取最大宽高)等
double x = SystemParameters.WorkArea.Width;//得到屏幕工作区域宽度 double y = SystemParameters.WorkArea.Height; ...
- JavaScript高级程序设计第20章JSON 笔记 (学习笔记)
第二十章 JSON 1.Json 可以表示三种类型的值: 1.简单值: 表示数值:5 表示字符串:“hello wrold”注表示字符串时必须使用双引号 2.对象: {“name”:“mi”,”ag ...
- .net转php laraval框架学习系列(二)项目实战---Models
上一篇已经介绍开发环境的搭建,如果有问题可以在文章后留言. 这篇将从项目实战开发,一步一步了解laravel框架. 在开发mvc项目时,models都是第一步. 下面就从建模开始. 实体关系图 由于不 ...
- Linux基础知识入门
[Linux基础]Linux基础知识入门及常见命令. 前言:最近刚安装了Linux系统, 所以学了一些最基本的操作, 在这里把自己总结的笔记记录在这里. 1,V8:192.168.40.10V1: ...
- Method Swizzling以及AOP编程:在运行时进行代码注入-备用
概述 今天我们主要讨论iOS runtime中的一种黑色技术,称为Method Swizzling.字面上理解Method Swizzling可能比较晦涩难懂,毕竟不是中文,不过你可以理解为“移花接木 ...
- 『安全科普』HTTP协议讲解及手工模拟发送
学习,熟悉HTTP协议,便于以后进行HTTP重放攻击! 0x 01 HTTP协议 查看HTTP协议 先查看鼠标点击一个链接后,浏览器发出了怎样的HTTP请求. Chrome浏览器下,按F12进入开发者 ...
- qt http 下载文件
本文章介绍如何利用HTTP从网站上下载文件.在Qt网络编程中,需要用到协议,即HTTP.它是超文本传输协议,它是一种文件传输协议.对于HTTP就不多解释了. 在Qt网络编程中,需要用到协议,即HTTP ...
- Cmake ,Out of Source Build
Out of Source build呢,就是让Cmake产生的临时垃圾文件,不关乎于项目实际本身的文件放到一个目录里,一般我们把这个目录放在项目根目录(也可以认为是根CmakeLists.txt)下 ...