//strvec.cc#include <string>
#include <iostream>
#include <memory>
#include "strvec.h"
using namespace std;//一个类对象是const的,它的元素不是const的
StrVec::StrVec(const StrVec &rhs)
{
//allocate_n_copy:可以开辟新的存储空间,然后把给定参数范围的元素逐个拷贝进去,然后
//返回构造好的空间的首元素地址和尾后元素的地址
pair<string*, string*> data = allocate_n_copy(rhs.elements,rhs.first_free);
elements = data.first;
first_free  = cap = data.second;
}
StrVec& StrVec::operator=(const StrVec & rhs)
{auto data = allocate_n_copy(rhs.begin(),rhs.end());free();             //拷贝赋值运算符比拷贝构造函数多一个释放左侧对象的空间的函数elements = data.first;first_free = cap  = data.second;return *this;
}
size_t StrVec::capacity()const
{return  cap - elements;
}
size_t StrVec::size()const
{return  first_free - elements;
}void StrVec::free()
{
if(elements){for(string * p = first_free; p != elements;){alloc.destroy(-- p);        }alloc.deallocate(elements,cap - elements);  //cap -elements 可以计算一共有多少空间}
}void StrVec::chk_n_alloc()
{
//如果容器已满,那么重新分配
if(size() == capacity())reallocate();
}pair<string*,string*> StrVec::allocate_n_copy(const string* b,const string * e)
{string * const data = alloc.allocate(e - b);return {data,uninitialized_copy(b,e,data)};}
allocator<string> StrVec::alloc;void StrVec::reallocate_1()
{
size_t new_capacity = size() ? 1 : 2 * size();
auto new_elements = alloc.allocate(new_capacity);
auto new_first_free = uninitialized_copy(elements,first_free,new_elements);
free();
auto new_cap = new_elements + new_capacity;
elements = new_elements;
first_free = new_first_free;
cap = new_cap;
}void StrVec::reallocate()
{auto new_capacity = size() ? 2*size() : 1;
auto new_elements = alloc.allocate(new_capacity);
auto dest = new_elements;
auto elem = elements;
for(int i = 0; i != size() ; ++ i)
{//std::move(),在需要构造的地方也是可以使用的 alloc.construct(dest ++,std::move(*elem++));
}
free();
elements = new_elements;
first_free = dest;
cap = new_elements + new_capacity;}void StrVec::push_back(const string & rhs)
{chk_n_alloc(); //确保有空间容纳新元素alloc.construct(first_free ++,10,'c');}void StrVec::pop_back()
{alloc.destroy(first_free --);
}StrVec::~StrVec()
{free();
}string * StrVec::begin()const
{return elements;
}
string * StrVec::end()const
{return first_free;
}void StrVec::reserve(size_t s)
{
if(s <= size()) return  ;//先移动元素,然后再释放左侧对象空间
auto  const new_elements = alloc.allocate(s);
auto  dest = new_elements;
auto  elem = elements;
for(size_t i = 0; i != size();++ i )    {alloc.construct(dest ++, std::move(*elem ++));}
free();
elements = new_elements;
cap = new_elements + s;
first_free = dest;}void StrVec::resize(size_t t)
{
if(t > capacity())return ;   else if(t < size()){auto new_first_free = first_free;for(size_t i = 0; i != size() - t; ++ i){alloc.destroy(-- new_first_free);}first_free = new_first_free;return;}
else if(t == size()){return ;}
else if(t > size()){auto new_first_free = first_free;for(size_t  i = 0;i != t - size() ; ++ i){alloc.construct(new_first_free ++,"");       }    first_free = new_first_free;  return;}
}void StrVec::print_info()const
{
cout << "capacity:" << capacity() << endl;
cout << "size:" <<size()<< endl;
}

文件main.cc

#include <string>
#include <iostream>
#include <memory>
#include "strvec.h"
using namespace std;
int main()
{
StrVec v;
//cout << v.capacity() << endl;
//cout << v.size() << endl;for(int i = 0;i != 10; ++i){v.push_back(string("abcde"));cout << v.size() << endl;}
cout <<"capacity:" << v.capacity() << endl;
cout <<"size:" <<  v.size() << endl;for(string * p = v.begin(); p != v.end(); ++p)cout << *p << endl;
v.print_info();v.resize(5);
v.resize(5);
v.resize(100);
cout << "big" << endl;
v.print_info();
v.reserve(100);
v.print_info();
cout << "after resize: " << endl;
for(string* p = v.begin(); p != v.end(); ++ p)cout << *p << endl;
v.print_info();return 0;
}
//strvec.h
#include <string>
#include <iostream>
#include <memory>
using namespace std;
class StrVec
{public:StrVec(): //allocator成员进行默认初始化elements(nullptr),first_free(nullptr),cap(nullptr){}StrVec(const StrVec &); //拷贝构造函数StrVec& operator=(const StrVec &);~StrVec();void push_back(const string &);void pop_back();size_t size()const;size_t capacity()const;string *begin()const;string *end()const;//习题13.39void resize(size_t );void reserve(size_t );void shrink_to_fit();void print_info()const;private:static allocator<string> alloc;string *elements;    //指向指向数组首元素的指针string *first_free;  //指向第一个空闲元素的指针string *cap;   //指向数组尾后位置的指针void free();  //销毁元素并且释放内存void reallocate_1(); 获得更多内存并拷贝已有元素void reallocate();pair<string*,string*> allocate_n_copy(const string*,const string*);//开辟空间,拷贝给定范围的元素void chk_n_alloc();};

运行结果:

1
2
3
4
5
6
7
8
9
10
capacity:16
size:10
cccccccccc
cccccccccc
cccccccccc
cccccccccc
cccccccccc
cccccccccc
cccccccccc
cccccccccc
cccccccccc
cccccccccc
capacity:16
size:10
big
capacity:16
size:5
capacity:100
size:5
after resize:
cccccccccc
cccccccccc
cccccccccc
cccccccccc
cccccccccc
capacity:100
size:5

strvec.h中虽然申明了shrink_to_fit,但是这个函数目前实现不了,因为allocator对象分配的空间,目前不能释放一部分;因为释放allocator对象分配的空间需要函数deallocate函数,这个函数形如:

deallocate(p,n);其中p必须是先前调用allocate得到的指针,而且n必须是先前调用allocate时候的空间的大小。

所以只能全部释放呀。不能部分释放。所以shrink_to_fit是不能实现的。

习题13.40自编答案

StrVec::StrVec(initializer_list<string> li)
{
//迭代器可以直接给指针赋值,棒呀,都什么情况可以这样操作呢?
auto data = allocate_n_copy(li.begin(),li.end());
elements = data.first;
first_free = cap = data.second;
}

练习13.42

c++ primer 习题13.39自己做的答案相关推荐

  1. c++ primer 5th,习题13.3 答案是不是错了?(未解决)

    c++ primer 5th,习题13.3 答案是不是错了?如下: 这两个类都未定义拷贝构造函数,因此编译器为它们定义了合成的拷贝构造函数.合成的拷贝构造函数逐个拷贝非 const成员,对内置类型的成 ...

  2. 2019-10-16 13:39:37,494 ERROR [http-nio-8080-exec-10] util.JWTUtils (JWTUtils.java:76) - The Token h

    Token过期 2019-10-16 13:39:37,494 ERROR [http-nio-8080-exec-10] util.JWTUtils (JWTUtils.java:76) - The ...

  3. C++Primer 习题 第7章

    C++Primer 习题 第7章 Person.h#ifndef PERSON_H #define PERSON_H #include<iostream> #include<stri ...

  4. 高等数学(第七版)同济大学 习题1-3 个人解答

    高等数学(第七版)同济大学 习题1-3 1. 对 图 1 − 26 所 示 的 函 数 f ( x ) , 求 下 列 极 限 , 如 极 限 不 存 在 , 说 明 理 由 . \begin{ali ...

  5. (记录)华为机试练习题13—句子逆序

    华为机试练习题13-句子逆序 题目描述 输入描述: 输出描述 例如: 代码(Java) 题目描述 将一个英文语句以单词为单位逆序排放.例如"I am a boy",逆序排放后为&q ...

  6. “笨办法”学Python3,Zed A. Shaw, 习题13

    习题13 代码 遇到问题 学到的 代码 from sys import argv # read the WYSS aection for how to run this script, first, ...

  7. 谭浩强C++课后习题13——整数转化为字符串,求i平方和

    谭浩强C++课后习题13--整数转化为字符串,求i平方和 题目一:用递归法将一个整数n转化为字符串.例如,输入483,应输出字符串"483".n的位数不确定,可以是任意位数的整数. ...

  8. 雷军:小米 13 暂无做半代升级版本计划;微软放宽 Bing 搜索引擎使用限制;.NET 8 发布首个预览版本|极客头条...

    「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 整理 | 梦依丹 出品 | CSDN(ID:CSDNnews ...

  9. C++ primer (中文版-第五版 )练习题答案

    C++ primer (中文版-第五版 ) 练习题答案 第1章 开始 1.4控制流 1.4.1节 while语句练习 1.4.2节 for语句练习 1.4.3节 读取数量不定的输入数据练习 1.4.4 ...

最新文章

  1. 开发日记-20190425 关键词 gradle基础学习 7年之约 启动篇
  2. JspWriter与PrintWriter的关系
  3. 《复盘+》把经验转化为能力
  4. scrum项目协作是什么_什么是小型Scrum?
  5. Ruby的Range类
  6. 剑指offer面试题[42]-反转单词顺序VS左旋转字符串
  7. 搜索不包含关键词_关键词排名:搜索同一个关键词,每次的排名却不一样?
  8. 手机抢答器正在替代传统抢答器
  9. 【AMAD】beaker -- 用于session和缓存的WSGI中间件
  10. 数据结构练习题――中序遍历二叉树
  11. RTMP、RTSP、HTTP协议流常用直播流地址
  12. 计算机专业学微积分有什么用,学微积分有什么用啊?
  13. 银河麒麟操作系统搭建本地源
  14. 流体力学(水力学)满分实验报告——伯努利方程
  15. 使用 IndexedDB 进行大数据存储
  16. 80后使用吵架约定,非常实用
  17. 内网,网关,外网三者的关系
  18. 响应式报名系统源码(含数据库脚本)
  19. Uni-app使用原生aar本地包云打包报错
  20. iOS开发之三大计时器(Timer、DispatchSourceTimer、CADisplayLink)

热门文章

  1. Runtime.getRuntime().exec()
  2. Mac10.9 Mavericks 输入法切换快捷键
  3. CSS实现的阴影效果
  4. iOS之深入解析Block的底层原理
  5. 华为有造车实力,却坚决不造整车,这背后有着怎样的无奈与思考?
  6. 树莓派AI视觉云台——6、Linux常用命令及vim编辑器的使用
  7. PaddlePaddle训练营——公开课——AI核心技术掌握——第1章迈入现代人工智能的大门——深度学习的基础算法——反向传播算法简介
  8. 【Java13】cookiesession(登陆案例(2)),jsp(登录案例(3))
  9. 【机器视觉】 dev_set_line_width算子
  10. 【Linux】一步一步学Linux——rename命令(36)