【足迹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]浮点值,小数类型 ...
随机推荐
- VLV INDEX
Normally, when the Directory Server conducts a search, the server looks through the entire entry for ...
- centos7上使用yum安装mysql
centos yum是没有mysql的,集成的是新的Mariadb,怎么用yum的方式在centos7上安装mysql呢? 1. 下载mysql的repo源 wget http://repo.mysq ...
- Java ----------- 正则表达式(更新中。。。。。。)
RegEx:Regular Expression. 元字符 描述 \ 将下一个字符标记符.或一个向后引用.或一个八进制转义符.例如,“\\n”匹配\n.“\n”匹配换行符.序列“\\”匹配“\”而“\ ...
- AngularJs练习Demo13Provider_factory
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...
- ORA-02447: cannot defer a constraint that is not deferrable
一个constraint如果被定义成deferrable那么这个constraints可以在deferred和imediate两种状态相互转换. deferred只在transaction中有效,也就 ...
- iOS 使用GitHub托管代码(github desktop使用)
iOS 使用GitHub托管代码 代码托管 1.首先得有一个GitHub的账号,没有的话就去https://github.com注册一个吧. 2.下载GitHub Mac客户端:http://mac. ...
- 模板模式(Template)
行为型:Template(模板模式) 作为一个曾经爱好写文章,但是不太懂得写文章的人,我必须承认,开头是个比较难的起步. 模板模式常规定义:模板模式定义了一个算法步骤,把实现延迟到子类. 事实上模板模 ...
- 武汉科技大学ACM :1004: C语言程序设计教程(第三版)课后习题6.3
Problem Description 求Sn=2+22+222+…+22…222(有n个2)的值. 例如:2+22+222+2222+22222(n=5),n由键盘输入. Input n Outpu ...
- jdbc 获取connection 对象的三种方式
获取数据库连接方法一:驱动实现类 //创建mysql的Driver对象 Driver driver=new com.mysql.jdbc.Driver(); //jdbc url 定位一个数据库: S ...
- JavaScript进阶学习的一些建议
blankyao最近问我如何学习JavaScript,他觉着在理解了JavaScript的语法之后,不知如何去学习JavaScript了. 其实我也是个JavaScript小菜,最近在开发中遇到不少关 ...