美文网首页
c++primer 14.16-14.29

c++primer 14.16-14.29

作者: 青吟乐 | 来源:发表于2019-06-13 07:25 被阅读0次

14.16
首先是StrBlob类

#ifndef STRBLOB_H_INCLUDED
#define STRBLOB_H_INCLUDED


#include <string>
#include <vector>
#include <initializer_list>
#include <memory>
#include <stdexcept>

using namespace std;
class StrBlobPtr;
class StrBlob{
    //重载==
    friend bool operator==(const StrBlob&, const StrBlob&);
    //重载!=
    friend bool operator!=(const StrBlob&, const StrBlob&);

public:
    friend class StrBlobPtr;
    typedef vector<string>::size_type size_type;
    StrBlob();
    StrBlob(initializer_list<string> il);
    //拷贝构造函数
    StrBlob(const StrBlob& a){
        data = make_shared<vector<string>>(*a.data);
    }
    //拷贝赋值运算符
    StrBlob& operator=(const StrBlob & a){
        data =make_shared<vector<string>>(*a.data);
        return *this;
    }
    size_type size() const{
        return data->size();
    }
    bool empty(){
        return data->empty();
    }
    //添加删除元素
    void push_back(const string &t){
        data->push_back(t);
    }
    void pop_back();

    //访问元素
    string & front();
    const string & front ()const;
    string & back();
    const string & back ()const;


private:
    shared_ptr<vector<string>> data;
    //如果data[i]不合法,抛出一个异常
    void check(size_type i,const string &msg) const;
    StrBlobPtr begin();
    StrBlobPtr end();
};


bool operator==(const StrBlob& a, const StrBlob& b){
    return a.data == b.data;
}
 bool operator!=(const StrBlob&a, const StrBlob&b){
     return !(a.data == b.data);
 }
class StrBlobPtr
{
public:
    StrBlobPtr() :curr(0) {}
    StrBlobPtr(StrBlob &a, size_t sz = 0) :wptr(a.data), curr(sz) {}

    string& deref() const//显示当前指向的vector的元素
    {
        auto p = check(curr, "dereference past end");
        return (*p)[curr];
    }
    StrBlobPtr& incr()//指针前移
    {
        check(curr, "increment past end of StrBlobPtr");
        ++curr;
        return *this;
    }

private:
    std::shared_ptr<vector<string>> check(size_t i, const string &msg) const
    {
        auto ret = wptr.lock();//检查是否空链接,lock()返回空指针
        if (!ret) throw std::runtime_error("unbound StrBlobPtr");//空链处理
        if (i >= ret->size()) throw std::out_of_range(msg);//输出错误信息
        return ret;//返回指针
    }
    std::weak_ptr<vector<string>> wptr;
    size_t curr;
};



//构造函数
StrBlob::StrBlob():data(make_shared<vector<string>>()){}
StrBlob::StrBlob(initializer_list<string> il):data(make_shared<vector<string>>(il)){}

//检查容器内元素是否存在的方法
void StrBlob::check(size_type i,const string &msg)const{
    if(i>=data->size()){
        throw out_of_range(msg);
    }
}

//访问元素的方法
string & StrBlob::front(){
    //如果vector为空,check将会抛出异常
    check(0,"front on empty Str");
    return data->front();
}
const string & StrBlob::front ()const{
    check(0,"front on empty Str");
    return data->front();
}

string & StrBlob::back(){
    check(0,"back on empty Str");
    return data->back();
}
const string & StrBlob::back ()const{
    check(0,"back on empty Str");
    return data->back();
}
void StrBlob::pop_back(){
    check(0,"pop_back on empty Str");
    data->pop_back();
}

StrBlobPtr StrBlob::begin(){
        return StrBlobPtr(*this);
    }
StrBlobPtr StrBlob::end(){
        auto ret = StrBlobPtr(*this,data->size());
        return ret;
    }



#endif // STRBLOB_H_INCLUDED

然后是StrblobPtr类

#ifndef STRBLOBPRE_H_INCLUDED
#define STRBLOBPRE_H_INCLUDED
#include <string>
#include <vector>
#include <initializer_list>
#include <memory>
#include <stdexcept>
#include "StrBlob.h"
using std::vector; using std::string;
class StrBlobPtr
{
    //重载==
    friend bool operator==(const StrBlobPtr&, const StrBlobPtr&);
    //重载!=
    friend bool operator!=(const StrBlobPtr&, const StrBlobPtr&);
public:
    StrBlobPtr() :curr(0) {}
    StrBlobPtr(StrBlob &a, size_t sz = 0) :wptr(a.data), curr(sz) {}

    string& deref() const
    {
        auto p = check(curr, "dereference past end");
        return (*p)[curr];
    }
    StrBlobPtr& incr()
    {
        check(curr, "increment past end of StrBlobPtr");
        ++curr;
        return *this;
    }

private:
    std::shared_ptr<vector<string>> check(size_t i, const string &msg) const
    {
        auto ret = wptr.lock();
        if (!ret) throw std::runtime_error("unbound StrBlobPtr");
        if (i >= ret->size()) throw std::out_of_range(msg);
        return ret;
    }
    std::weak_ptr<vector<string>> wptr;
    size_t curr;
};
bool operator==(const StrBlobPtr&a, const StrBlobPtr&b){
    return a.wptr == b.wptr;
}
bool operator!=(const StrBlobPtr&a, const StrBlobPtr&b){
    return !(a.wptr == b.wptr);
}
#endif // STRBLOBPRE_H_INCLUDED

继续是StrVec类

#ifndef STRVEC_H_INCLUDED
#define STRVEC_H_INCLUDED
#include<memory>
#include<algorithm>
/**类似于vector内存分配策略的简化实现*/
class StrVec{
    //重载==
    friend bool operator==(const StrVec&, const StrVec&);
    //重载!=
    friend bool operator!=(const StrVec&, const StrVec&);
public:
    StrVec(std::initializer_list<std::string> il);
    StrVec(): elements(nullptr),first_free(nullptr),cap(nullptr){}          //allocator成员进行默认初始化
    StrVec(const StrVec&);              //拷贝构造函数
    StrVec &operator=(const StrVec&);   //拷贝赋值运算符
    ~StrVec();


    StrVec(StrVec &&s) noexcept;        //移动构造函数
    StrVec &operator=(StrVec &&rhs) noexcept;

    void push_back(const std::string&); //拷贝元素
    void push_back(std::string &&);
    size_t size() const{                //长度
        return first_free-elements;
    }
    size_t capacity() const {
        return cap - elements;
    }
    std::string *begin()const{
        return elements;
    }
    std::string *end()const{
        return first_free;
    }




private:
    std::allocator<std::string> alloc;//分配元素
    //被添加元素的函数与实用
    void chk_n_alloc(){
        if(size() == capacity()){
            reallocate();
        }
    }
    //工具函数 :被拷贝构造函数,赋值运算符和析构函数所使用
    std::pair<std::string*,std::string*> alloc_n_copy(const std::string*,const std::string*);
    void free();                        //销毁元素并且释放内存
    void reallocate();                  //获得更多内存并且拷贝元素
    std::string *elements;              //指向数组首元素的指针
    std::string *first_free;            //指向数组第一个空闲元素的指针
    std::string *cap;                   //指向数组尾后位置的指针
    void alloc_n_move(size_t n);        //申请n长的内存块
    void reserve(size_t n);             //分配至少能容下n个元素的内存空间
    void resize(size_t n);              //分配至少能容下n个元素的内存空间,空位置值初始化
};
//重载==
bool operator==(const StrVec&a, const StrVec&b){
   auto aa = a.begin();
   auto bb = b.begin();
   while(aa!= a.end()&&bb!=b.end()){
        if(*aa != *bb){
            return 0;
        }
   }
   return 1;
}
//重载!=
bool operator!=(const StrVec&a, const StrVec&b){

   return !(a==b);
}
void StrVec::push_back(const std::string&s){
    chk_n_alloc();                      //确保有空间容纳新的元素
    alloc.construct(first_free++,s);    //在first_free指向的元素中构造s的副本
}

std::pair<std::string*,std::string*> StrVec::alloc_n_copy(const std::string *a , const std::string *e){
    //分配空间保存给定范围中的元素
    auto data = alloc.allocate(e-a);
    //初始化并返回一个pair,该pair是有data和uninitialized_copy的返回值构成
    auto llast = uninitialized_copy(a,e,data);
    return {data,llast};
}
/**
void StrVec::free(){
    //不能传递给deallocate一个空的指针,如果elements为0,函数什么也不做
    if(elements){
        for(auto p = first_free;p!=elements;){
            alloc.destroy(--p);//先destory销毁元素
        }
        alloc.deallocate(elements,cap - elements);//释放元素占用的内存
    }
}*/
void StrVec::free(){
    if(elements){
        for_each(elements,first_free,[this](std::string &s){alloc.destroy(&s);});
        alloc.deallocate(elements,cap - elements);//释放元素占用的内存
    }

}
StrVec::StrVec(const StrVec &s){
    //调用alloc_n_copy分配空间以容纳与s中一样多的元素
    auto newdata = alloc_n_copy(s.begin(),s.end());
    elements = newdata.first;
    first_free = cap = newdata.second;
}
StrVec::~StrVec(){
    free();
}
StrVec &StrVec::operator=(const StrVec &rhs){
    //调用alloc_n_copy分配内存,大小与rhs中元素占用空间一样多
    auto data = alloc_n_copy(rhs.begin(),rhs.end());
    free();
    elements = data.first;
    first_free = cap = data.second;
    return *this;
}
/**
void StrVec::reallocate(){
    //分配当前两倍大小的内存空间
    auto newcapacity = size() ? 2*size() :1;
    //分配新内存
    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;
}
*/
void StrVec::reallocate(){
    auto newcapacity = size() ? 2*size() :1;
    auto first = alloc.allocate(newcapacity);

    auto last = std::uninitialized_copy(make_move_iterator(begin()),make_move_iterator(end()),first);

    free();
    elements = first;
    first_free = last;
    cap = elements+newcapacity;
}

//13.39
void StrVec::alloc_n_move(size_t n)
{
    //申请n长的内存块
    auto newdata = alloc.allocate(n);
    //该内存块起始点
    auto dest = newdata;
    //指示旧元素地址的起始
    auto elem = elements;
    //在新内存挨个使用移动构造函数构造进新内存
    for (size_t i = 0; i != size(); ++i)
        alloc.construct(dest++, std::move(*elem++));
    free();//构造完毕后释放旧内存
    //更新当前StrVec属性
    elements = newdata;
    first_free = dest;
    cap = elements + n;
}

void StrVec::reserve(size_t n)
{
    if (n <= capacity()) return;        //若是要求的内存长度小于当下长度,直接返回,什么也不做
    alloc_n_move(n);                    //分配n个长度的空间
}


void StrVec::resize(size_t n){
    if(n>size() ){//比当前大分两种情况,一种是比最大容量还要大,另一种是小于最大容量
        if(n>capacity()){
            reserve(2*n);
        }
        for(size_t i =size();i!=n;i++){
            alloc.construct(first_free++," ");
        }
    }else if(n<size()){//比当前小就要从后往前一个个销毁
        while(first_free!= elements+n){
            alloc.destroy(first_free);
            first_free--;
        }
    }
}
StrVec::StrVec(std::initializer_list<std::string> il){
    auto newdata = alloc_n_copy(il.begin(),il.end());
    elements = newdata.first;
    first_free  = cap = newdata.second;
}
//移动构造函数
StrVec::StrVec(StrVec &&s) noexcept:elements(s.elements),first_free(s.first_free),cap(s.cap){
    //另s进入这样的状态-----对其运行析构函数是安全的
    s.elements = s.first_free = s.cap = nullptr;
}
//移动赋值运算符
StrVec &StrVec::operator=(StrVec &&rhs) noexcept{
    //首先检测自身赋值
    if(this != &rhs){
        free();                                 //释放已有元素
        elements = rhs.elements;                //从rhs接管资源
        first_free = rhs.first_free;
        cap = rhs.cap;
        //将rhs置于可析构的状态
        rhs.elements = rhs.first_free = rhs.cap = nullptr;
    }
    return *this;
}
void StrVec::push_back(std::string &&s){
    chk_n_alloc();                      //确保有空间容纳新的元素
    alloc.construct(first_free++,std::move(s));    //在first_free指向的元素中构造s的副本
}

#endif // STRVEC_H_INCLUDED

最后是String

#ifndef STRING_H_INCLUDED
#define STRING_H_INCLUDED

#include <string>
#include <algorithm>
#include <memory>
#include <vector>
#include<iostream>
class String{
    //重载<<
    friend std::ostream& operator<<(std::ostream&, const String&);
    //重载==
    friend bool operator==(const String&, const String&);
    //重载!=
    friend bool operator!=(const String&, const String&);
public:
    String():String(""){}                                        //默认构造函数
    String(const char *s){
        auto s1 = const_cast<char*> (s);             //const_cast的作用就是解const
        for(;*s1;s1++){range_initializer(s, s1);}                              //计算字符长度
                                  //申请内存
    }
    String(const String&);
    String & operator=(const String& );
    ~String(){
        free();
    }
    void free(){
        if(elements){//若elements不为空
            std::for_each(elements,first_free,[this](char &c){alloc.destroy(&c);});
            alloc.deallocate(elements,first_free-elements);
        }
    }


    //移动构造函数
    String(String &&s) noexcept;
    //移动构造运算符
    String & operator=(String &&rhs) noexcept;
    void range_initializer(const char*, const char*);
    const char *c_str() const { return elements; }
private:
    std::allocator<char> alloc;                      //用于申请内存
    char *elements;                                  //首指针
    char *first_free;                                //尾后指针

    std::pair<char*,char*> alloc_n_copy(const char *a,const char *b){
        auto first_address = alloc.allocate(b-a);                        //返回申请内存的首指针
        auto last_f_address = std::uninitialized_copy(a,b,first_address);//返回构造后的尾后指针
        return {first_address,last_f_address};                           //以pair的形式返回
    }
};
//重载==
bool operator==(const String&a, const String&b){
    char *aa = const_cast<char*>(a.c_str());
    char *bb = const_cast<char*>(b.c_str());
    while(aa&&bb){
        if(*aa!=*bb){
            return false;
        }
    }
    return true;
}
//重载!=
bool operator!=(const String&a, const String&b){
    return !(a==b);
}
void String::range_initializer(const char *first, const char *last)
{
    auto newstr = alloc_n_copy(first, last);
    elements = newstr.first;
    first_free = newstr.second;
}



String::String(const String&s){
    std::cout<<"拷贝构造函数"<<std::endl;
    auto newStr = alloc_n_copy(s.elements,s.first_free);
    elements = newStr.first;
    first_free = newStr.second;
}

String& String::operator=(const String&a){
    std::cout<<"拷贝赋值运算符"<<std::endl;
    auto newc = alloc_n_copy(a.elements,a.first_free);
    free();
    elements = newc.first;
    first_free = newc.second;
    return *this;
}
//移动构造函数
String::String(String &&s) noexcept{
    std::cout<<"移动构造函数"<<std::endl;
    elements = s.elements;
    first_free = s.first_free;
    s.elements = s.first_free = nullptr;

}
//移动赋值运算符
String &String::operator=(String &&rhs) noexcept{
    std::cout<<"移动赋值运算符"<<std::endl;
    if(this!=&rhs){
        free();
        elements = rhs.elements;
        first_free = rhs.first_free;
        rhs.elements = rhs.first_free = nullptr;
    }
    return *this;
}
std::ostream& operator<<(std::ostream &os, const String &s)
{
    char *c = const_cast<char*>(s.c_str());
    while (*c)
        os << *c++;
    return os;
}

#endif // STRING_H_INCLUDED

14.17
有必要,book类不需要对编号进行比较
代码见14.5
14.18
StrBlob的<

bool operator<(const StrBlob&a, const StrBlob&b){
    return a.size()<b.size();
 }

StrBlobPtr的<

bool operator<(const StrBlobPtr & a, const StrBlobPtr & b){
    auto ret1 = a.wptr.lock();
    auto ret2 = a.wptr.lock();
    if(ret1&&ret2){
        return ret1->size()<ret2->size();
    }else{
        return false;
    }
}

String的<

bool operator<(const String&a, const String&b){
    auto size1 = a.first_free-a.elements;
    auto size2 = b.first_free-b.elements;
    return size1<size2;
}

StrVec的<

bool operator<(const StrVec&a, const StrVec&b){
    return a.size()<b.size();
}

14.19
并不需要,找不到唯一逻辑可靠的<关系
14.20
Sales_data重载+=运算符

//实现+=运算符
Sales_data& Sales_data::operator+=(const Sales_data &rhs)
{
    units_sold += rhs.units_sold;
    revenue += rhs.revenue;
    return *this;
}

Sales_data重载+运算符

//实现+运算符
Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs)
{
    Sales_data sum = lhs;//拷贝lhs到sum
    sum += rhs;//进行对象的加法运算
    return sum;//返回对象的合成移动拷贝(右值)
}

14.21
我上一题使用的是和以前一样的版本,也就是体现出优点的版本
若是单独定义+,会多使用一个Sales_data 的临时对象
14.22
使用一个单参构造即可

Sales_data& Sales_data::operator=(const std::string&x){
    *this = Sales_data(x);
    return *this;
}

14.23
两个重载=一起看
声明

    StrVec &operator=(const StrVec&);   //拷贝赋值运算符
    StrVec & operator=(const std::initializer_list<std::string> il);

实现

StrVec &StrVec::operator=(const StrVec &rhs){
    //调用alloc_n_copy分配内存,大小与rhs中元素占用空间一样多
    auto data = alloc_n_copy(rhs.begin(),rhs.end());
    free();
    elements = data.first;
    first_free = cap = data.second;
    return *this;
}
StrVec::StrVec(std::initializer_list<std::string> il){
    auto newdata = alloc_n_copy(il.begin(),il.end());
    elements = newdata.first;
    first_free  = cap = newdata.second;
}

14.24
我用的book,每本书有唯一的编号,需要自己定义拷贝赋值运算符,具体略。。
14.25

14.26
StrVec的下标运算符

class StrVec{
public:
    std::string &operator[](std::siez_t n)              // 非常量版本
    { return elements[n]; }
    const std::string &operator[](std::size_t n) const  // 常量版本
    { return elements[n]; }
private:
    std::string *elements; // 指向数组首元素的指针
};

StrBlob下标运算符

//定义下标运算符
    std::string&  operator[](int n){//普通对象使用
        int i = 0;
        for(auto c:*data){
            i++;
            if(i == n){
                cout<<c<<endl;
            }
        }
    }
    const std::string&  operator[](int n)const{//常量对象使用
        int i = 0;
        for(auto c:*data){
            i++;
            if(i == n){
                cout<<c<<endl;
            }
        }
    }

StrBlobPtr运算符

    //定义下标运算符
    std::string&  operator[](int n){//普通对象使用
        auto ret = wptr.lock();
        if(ret){
            int i = 0;
            for(auto c:*ret){
                i++;
                if(i == n){
                cout<<c<<endl;
            }
          }
        }else{
            cout<<"下标越界"<<endl;
        }

    }
    const std::string&  operator[](int n)const{//常量对象使用
        auto ret = wptr.lock();
        if(ret){
            int i = 0;
            for(auto c:*ret){
                i++;
                if(i == n){
                cout<<c<<endl;
            }
          }
        }else{
            cout<<"下标越界"<<endl;
        }
    }

String的下标运算符


    char & operator[](std::size_t n){//普通对象使用
        return elements[n];
    }
    const char & operator[](std::size_t n) const {//常量对象使用
        return elements[n];
    }

14.27
实现了书上的版本

#ifndef STRBLOB_H_INCLUDED
#define STRBLOB_H_INCLUDED


#include <string>
#include <vector>
#include <initializer_list>
#include <memory>
#include <stdexcept>
#include<iostream>

using namespace std;
class StrBlobPtr;
class StrBlob{
    //重载==
    friend bool operator==(const StrBlob&, const StrBlob&);
    //重载!=
    friend bool operator!=(const StrBlob&, const StrBlob&);
    //重载<
    friend bool operator<(const StrBlob&, const StrBlob&);

public:
    friend class StrBlobPtr;
    typedef vector<string>::size_type size_type;
    StrBlob();
    StrBlob(initializer_list<string> il);
    //拷贝构造函数
    StrBlob(const StrBlob& a){
        data = make_shared<vector<string>>(*a.data);
    }
    //拷贝赋值运算符
    StrBlob& operator=(const StrBlob & a){
        data =make_shared<vector<string>>(*a.data);
        return *this;
    }
    size_type size() const{
        return data->size();
    }
    bool empty(){
        return data->empty();
    }
    //添加删除元素
    void push_back(const string &t){
        data->push_back(t);
    }
    void pop_back();

    //访问元素
    string & front();
    const string & front ()const;
    string & back();
    const string & back ()const;
    //定义下标运算符
    std::string&  operator[](int n){//普通对象使用
        int i = 0;
        for(auto c:*data){
            i++;
            if(i == n){
                cout<<c<<endl;
            }
        }
    }
    const std::string&  operator[](int n)const{//常量对象使用
        int i = 0;
        for(auto c:*data){
            i++;
            if(i == n){
                cout<<c<<endl;
            }
        }
    }





private:
    shared_ptr<vector<string>> data;
    //如果data[i]不合法,抛出一个异常
    void check(size_type i,const string &msg) const;
    StrBlobPtr begin();
    StrBlobPtr end();
};



bool operator==(const StrBlob& a, const StrBlob& b){
    return a.data == b.data;
}
 bool operator!=(const StrBlob&a, const StrBlob&b){
     return !(a.data == b.data);
 }

 bool operator<(const StrBlob&a, const StrBlob&b){
    return a.size()<b.size();
 }

class StrBlobPtr
{
    //重载<
    friend bool operator<(const StrBlobPtr&a, const StrBlobPtr&b);
public:
    StrBlobPtr() :curr(0) {}
    StrBlobPtr(StrBlob &a, size_t sz = 0) :wptr(a.data), curr(sz) {}

    string& deref() const//显示当前指向的vector的元素
    {
        auto p = check(curr, "dereference past end");
        return (*p)[curr];
    }
    StrBlobPtr& incr()//指针前移
    {
        check(curr, "increment past end of StrBlobPtr");
        ++curr;
        return *this;
    }
    //定义下标运算符
    std::string&  operator[](int n){//普通对象使用
        auto ret = wptr.lock();
        if(ret){
            int i = 0;
            for(auto c:*ret){
                i++;
                if(i == n){
                cout<<c<<endl;
            }
          }
        }else{
            cout<<"下标越界"<<endl;
        }

    }
    const std::string&  operator[](int n)const{//常量对象使用
        auto ret = wptr.lock();
        if(ret){
            int i = 0;
            for(auto c:*ret){
                i++;
                if(i == n){
                cout<<c<<endl;
            }
          }
        }else{
            cout<<"下标越界"<<endl;
        }
    }
    //定义前置自增自减运算符
    StrBlobPtr& operator++();
    StrBlobPtr& operator--();


    //定义后置自增自减运算符
    StrBlobPtr& operator++(int);
    StrBlobPtr& operator--(int);

private:
    std::shared_ptr<vector<string>> check(size_t i, const string &msg) const
    {
        auto ret = wptr.lock();//检查是否空链接,lock()返回空指针
        if (!ret) throw std::runtime_error("unbound StrBlobPtr");//空链处理
        if (i >= ret->size()) throw std::out_of_range(msg);//输出错误信息
        return ret;//返回指针
    }
    std::weak_ptr<vector<string>> wptr;
    size_t curr;
};



//构造函数
StrBlob::StrBlob():data(make_shared<vector<string>>()){}
StrBlob::StrBlob(initializer_list<string> il):data(make_shared<vector<string>>(il)){}

//检查容器内元素是否存在的方法
void StrBlob::check(size_type i,const string &msg)const{
    if(i>=data->size()){
        throw out_of_range(msg);
    }
}

//访问元素的方法
string & StrBlob::front(){
    //如果vector为空,check将会抛出异常
    check(0,"front on empty Str");
    return data->front();
}
const string & StrBlob::front ()const{
    check(0,"front on empty Str");
    return data->front();
}

string & StrBlob::back(){
    check(0,"back on empty Str");
    return data->back();
}
const string & StrBlob::back ()const{
    check(0,"back on empty Str");
    return data->back();
}
void StrBlob::pop_back(){
    check(0,"pop_back on empty Str");
    data->pop_back();
}

StrBlobPtr StrBlob::begin(){
        return StrBlobPtr(*this);
    }
StrBlobPtr StrBlob::end(){
        auto ret = StrBlobPtr(*this,data->size());
        return ret;
    }

bool operator<(const StrBlobPtr & a, const StrBlobPtr & b){
    auto ret1 = a.wptr.lock();
    auto ret2 = a.wptr.lock();
    if(ret1&&ret2){
        return ret1->size()<ret2->size();
    }else{
        return false;
    }
}
//前置++
StrBlobPtr& StrBlobPtr::operator++(){
    //如果curr已经只指向了容器的末尾位置,则无法递增它
    check(curr,"后越界");
    ++curr;
    return *this;
}
//前置--
StrBlobPtr& StrBlobPtr::operator--(){
    //如果curr已经只指向了容器的末尾位置,则无法递增它
    --curr;
    check(curr,"前越界");
    return *this;
}
//后置++
StrBlobPtr& StrBlobPtr::operator++(int){
    //此处无需检查有效性
    StrBlobPtr ret = *this;
    ++*this;//使用前置++
    return ret;//返回之前记录的对象
}
//后置--
StrBlobPtr& StrBlobPtr::operator--(int){
    //此处无需检查有效性
    StrBlobPtr ret = *this;
    --*this;//使用前置--
    return ret;//返回之前记录的对象
}

#endif // STRBLOB_H_INCLUDED

14.28
自我感觉书上版本即可。。。。(懒了)
14.29
自增自减都是要对对象本身进行修改的,使用const毫无意义啊

相关文章

网友评论

      本文标题:c++primer 14.16-14.29

      本文链接:https://www.haomeiwen.com/subject/iywdfctx.html