把strblob中的vector<string> 换成strvec

练习13.42

//functions.cc
#include <string>
#include <iostream>
#include "strblob.h"
#include "strblobptr.h"
#include <vector>
#include "strvec.h"
using namespace std;//strblob.h成员函数实现
StrBlob::StrBlob():data(make_shared<StrVec>()){}
StrBlob::StrBlob(const StrVec &s):data(make_shared<StrVec>(s)){}StrBlob::size_type StrBlob::size()const{return data->size();
}
void StrBlob::push_back(const string &ele)
{data->push_back(ele);
}void StrBlob::pop_back(){data->pop_back();
}
string & StrBlob::front()
{
return data->front();}
string & StrBlob::back()
{
return data->back();
}
const string& StrBlob::front()const{return data->front();
}
const string& StrBlob::back()const{return data->back();
}bool StrBlob::empty()const
{
return data->empty();
}/* following is the member functions of class StrBlobPtr */
StrBlobPtr::StrBlobPtr():curr(0){}
StrBlobPtr::StrBlobPtr(StrBlob b,size_t i):wptr(b.data),curr(i){}shared_ptr<StrVec>
StrBlobPtr::check(size_t i,const string &msg)const{shared_ptr<StrVec> ret = wptr.lock();
//question1:什么情况下,ret会不指向任何对象呢?
if(!ret)throw runtime_error("unbounded StrBlobPtr");
else if(i >= ret->size())throw out_of_range(msg);
elsereturn ret;
}StrBlobPtr StrBlob::begin()const
{
return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()const
{
return StrBlobPtr(*this,this->size());
}string & StrBlobPtr::deref()const
{
auto ret = check(curr,"out of range");
return  *(ret->begin() + curr);
}StrBlobPtr &StrBlobPtr::incr()
{check(curr,"out of range");++ curr;return *this;
}//strvec.h
StrVec::StrVec():elements(nullptr),first_free(nullptr),cap(nullptr){}
allocator<string> StrVec::alloc;
string &StrVec::front()const
{
return *elements;}
string & StrVec::back()const
{
return *(first_free - 1);}
string *StrVec::begin()const
{
return elements;
}
string * StrVec::end()const
{
return first_free;
}StrVec::StrVec(const StrVec &s)
{
auto data = allocate_n_copy(s.begin(),s.end());
elements = data.first;
cap = first_free = data.second;
}
StrVec& StrVec::operator=(const StrVec& s)
{
auto data = allocate_n_copy(s.begin(),s.end());
free();
elements = data.first;
cap = first_free = data.second;return *this;
}pair<string*,string*> StrVec::allocate_n_copy(const string* b,const string *e)
{
string * new_elements = alloc.allocate(e - b);
string * dest = new_elements;
const string * elem = b;
while(elem != e){alloc.construct(dest ++,std::move(*elem ++)); }return {new_elements,dest};
}void StrVec::free()
{
auto elem = elements;
while(elem != first_free){alloc.destroy(elem ++);}
alloc.deallocate(elements,cap - elements);
}
size_t StrVec::size()const
{
return (first_free - elements);}
void StrVec::push_back(const string &s)
{
if(first_free == cap)reallocate();
alloc.construct(first_free ++ ,s);
}
void StrVec::pop_back()
{
check(0,"pop on empty StrVec.");
alloc.destroy(--first_free);
}
bool StrVec::empty()const
{
if(!elements)return true;
elsereturn false;}
StrVec::~StrVec()
{
free();
}void StrVec::reallocate()
{
size_t new_size = size()? 2*size():1;
auto new_elements = alloc.allocate(new_size);
auto new_first_free = uninitialized_copy(elements,first_free,new_elements);
free();
elements = new_elements;
first_free = new_first_free;
cap = new_elements + new_size;
}void StrVec::check(size_t i,const string &msg)const
{
if(i >= size())     throw out_of_range(msg);
}bool StrBlobPtr::operator!=(const StrBlobPtr &s)
{auto p = this->wptr.lock();auto q = s.wptr.lock();if(!(p->elements == q->elements && p->first_free == q->first_free && p->cap == q->cap))return true;elsereturn false;
}
//main.cc#include <string>
#include <iostream>
#include "strblob.h"
#include "strblobptr.h"
#include <vector>
#include "strvec.h"
using namespace std;
int main()
{
StrVec s1;
s1.push_back("abc");
s1.push_back("def");
s1.push_back("fgh");
s1.push_back("qhk");
//for(string* ptr = s1.begin(); ptr != s1.end() ;++ ptr)
//  cout << *ptr << endl;
for(auto p = s1.begin(); p != s1.end() ; ++p)cout << *p << endl;StrBlob str(s1);
StrBlobPtr pk(str);
pk.incr();cout << "deref :" << endl;
cout << pk.deref() << endl;
cout << "end ." << endl;
cout << str.size() << endl;
cout << str.empty() << endl;
cout << str.front() << endl;
cout << str.back() << endl;return 0;
}
//strblob.h
#ifndef STRBLOB_H
#define STRBLOB_H#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include "strvec.h"
using namespace std;
class StrBlobPtr;
class StrBlob{public:friend class StrBlobPtr;StrBlob();StrBlob(const StrVec &l);using size_type = vector<string>::size_type;size_type size()const;void push_back(const string &ele);void pop_back();string &front();string &back();const string &front()const;const string &back()const;bool empty()const;StrBlobPtr begin()const;StrBlobPtr end()const;private:shared_ptr<StrVec> data;void check(size_type i,const string &msg);};#endif
//strblobptr.h#ifndef INCLUDE_H_STRBLOBPTR
#define INCLUDE_H_STRBLOBPTR#include <string>
#include <iostream>
#include <memory>
#include <vector>
#include "strvec.h"
using namespace std;
class StrBlobPtr{public:
StrBlobPtr();
StrBlobPtr(StrBlob b,size_t curr = 0);
string & deref()const;
StrBlobPtr & incr();
bool operator!=(const StrBlobPtr &s);private:weak_ptr<StrVec> wptr;size_t curr;shared_ptr<StrVec>  check(size_t i,const string &msg)const;
};#endif
//strvec.h#ifndef STRVEC_H
#define STRVEC_H#include <string>
#include <iostream>
#include <memory>
using namespace std;
class StrVec
{friend class StrBlobPtr;public:StrVec();StrVec(const StrVec &);StrVec& operator=(const StrVec &);~StrVec();string & front()const;string & back()const;string * begin()const;string * end()const;void pop_back();void push_back(const string &s);size_t size()const;bool   empty()const;void reallocate();private:static allocator<string> alloc;string * elements;string * first_free;string * cap;pair<string*,string*> allocate_n_copy(const string *,const string *);void free();//主要检查是否i已经达到容器的尾后位置void check(size_t i,const string &msg)const;
};#endif

在g++编译器中执行:

g++ main.cc functions.cc -o exe
./exe

得到如下结果:

abc
def
fgh
qhk
deref :
def
end .
4
0
abc
qhk

结果,目前来来,全部通过编译。

c++primer练习13.42相关推荐

  1. c++ primer 习题13.39自己做的答案

    //strvec.cc#include <string> #include <iostream> #include <memory> #include " ...

  2. 《C++ Primer》13.1.3节练习

    练习13.9: 析构函数完成与构造函数相反的工作:释放对象使用的资源,销毁非静态数据成员.从语法上看,它是类的一个成员函数,名字是波浪号接类名,没有返回值,也不接受参数. 当一个类没有定义析构函数时, ...

  3. 《C++ Primer》13.1.2节练习

    练习13.6: 拷贝赋值运算符本身是一个重载的赋值运算符,定义为类的成员函数,左侧运算对象绑定到隐含的this参数,而右侧运算对象是所属类类型的,作为函数的参数,函数返回指向其左侧运算对象的引用. 当 ...

  4. 《C++ Primer》13.1.1节练习

    练习13.1: 如果构造函数的第一个参数是自身类类型的引用,且所有其他参数(如果有的话)都有默认值,则此构造函数是拷贝构造函数.拷贝构造函数在以下几种情况下会被使用: ●拷贝初始化(用=定义变量). ...

  5. 《C++ Primer》13.1.6节练习(部分)

    练习13.18: #include <iostream> #include <string> using namespace std;class Employee {priva ...

  6. 《C++ Primer》13.1.4节练习

    练习13.14: 这是一个典型的应该定义拷贝控制成员的场合.如果不定义拷贝构造函数和拷贝赋值运算符,依赖合成的版本,则在拷贝构造和赋值时,会简单复制数据成员.对本问题来说,就是将序号简单复制给新对象. ...

  7. C++ primer 第13章 拷贝控制

    文章目录 前言 拷贝.赋值与销毁 拷贝构造函数 合成拷贝构造函数 拷贝初始化和直接初始化 拷贝初始化的发生: 参数和返回值 拷贝初始化的限制 拷贝赋值运算符 重载赋值运算符 合成拷贝赋值运算符 析构函 ...

  8. C++ primer 第13章 拷贝控制

    文章目录 前言 拷贝.赋值与销毁 拷贝构造函数 合成拷贝构造函数 拷贝初始化和直接初始化 拷贝初始化的发生: 参数和返回值 拷贝初始化的限制 拷贝赋值运算符 重载赋值运算符 合成拷贝赋值运算符 析构函 ...

  9. c++ primer 5th第13章拷贝控制知识点和自编习题答案

    首先,先给大家提个醒.在网上的随书源代码里关于hasptr类的类指针版本编写的移动构造函数.移动赋值运算符.和析构函数部分是有错误的.大家可以把hasptr累指针版本(里面带移动构造函数和移动赋值运算 ...

最新文章

  1. gulp-load-task 解决 gulpfile.js 过大的问题
  2. C++ limits头文件
  3. docker-compose.yml 启动jar 包
  4. python读取字典元素笔记_python学习笔记:字典的使用示例详解
  5. CentOS启动Tomcat巨慢
  6. 原子操作和杀死goroutine两种方法,解决多协程调用同一个函数的问题
  7. c语言spi测试代码,C语言程序SPI
  8. ajax send上传出错,AJAX + FormData 上传文件失败?
  9. Windows Server 2008 R2忘记管理员密码后的解决方法
  10. 09年关门歇业的15大网站 雅虎旗下4网站上榜
  11. 075 json和pickle模块
  12. 设计配色灵感|热情甜蜜色系配色方案
  13. ctfmon是什么启动项_启动项里找不到ctfmon
  14. https开头的网址是什么意思_网址是什么意思?基础知识普及
  15. 创业公司一年工作总结(转)(公司失败原因)
  16. thinkphp 运行机制和优缺点
  17. vi编辑器怎么不保存退出?
  18. Google Dremel数据模型详解(上)
  19. C Primer Plus课后习题
  20. 少儿Python编程6-计算机数据结构和算法

热门文章

  1. nodejs 框架 中文express 4.xxx中文API手册
  2. 实用的SqlHelper类
  3. Ubuntu14.04下搭建LAMP环境
  4. 【计算机图形学课程】一.MFC基本绘图函数使用方法
  5. iOS之深入解析如何构建静态库
  6. 【数据结构与算法】之有序数组中的单一元素的算法
  7. 2013\Province_C_C++_A\3.振兴中华
  8. 数据库开发——MySQL——数据的增删改查
  9. 百练2811:熄灯问题
  10. IDEA快捷键及使用技巧