【足迹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]浮点值,小数类型 ...
随机推荐
- java对象Integer不能引用传递
java对象Integer不能引用传递 /** * The value of the <code>Integer</code>. * * @serial */ private ...
- COM 浅谈
ArcObject 是基于 COM(Microsoft Component Object Model),即组件对象模型.虽然ArcGIS的终端用户不用理解什么是COM,但是作为基于ArcObject的 ...
- ORA-01810格式代码出现两次 的解决方案
今早做一个查询页面时,需要查询两个时间区间的跨度,使用TO_DATE函数,一开始写成了Sql代码 TO_DATE('2014-08-04 00:00:00','YYYY-MM-DD HH:mm:ss' ...
- Oracle物理结构与逻辑结构
有一张图能非常清晰的表示出Oracle物理结构与逻辑结构的区别:如下图: 对上图的解释:每个数据库都必须由一个或多个表空间组成.(一对多关系)每个表空间都必须由一个或多个数据文件(data fil ...
- Swift 循环、数组 字典的遍历
import Foundation // 数组声明 var arr = [String]() // 数组循环添加项 ...{ arr.append("Item \(index)") ...
- [Jquery] 操作html 不常用元素方法大全
除http://www.w3school.com.cn/jquery/jquery_selectors.asp上的以外该大全应都有. 第一章 input控件篇 1.操作select 下拉框 1.1 获 ...
- C#结构函数与base关键字
//声明父类 class ProductsFather { public double Price { get; set; } public int Count { get; set; } publi ...
- include,include_once,require,require_once的区别
1.include,require在其被调用的位置处包含一个文件. 2.include_once,require_once函数的作用与include相同,不过它会首先验证是否已包含该文件.如果已经包含 ...
- Django Meta内部类选项
http://blog.csdn.net/yelbosh/article/details/7545335
- 使用PHP解压文件Unzip
这是一个非常方便的PHP函数从.zip文件解压缩文件.它有两个参数:第一个是压缩文件的路径和第二 function unzip_file($file, $destination) { // creat ...