练习14.27:
class StrBlobPtr
{
friend bool operator==(const StrBlobPtr&, const StrBlobPtr&);
friend bool operator!=(const StrBlobPtr&, const StrBlobPtr&);
friend bool operator<(const StrBlobPtr&, const StrBlobPtr&);
friend bool operator<=(const StrBlobPtr&, const 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) { }
std::string& deref() const;
StrBlobPtr& incr();
//递增递减运算符
//前置版本
StrBlobPtr& operator++();
StrBlobPtr& operator--();
//后置版本,为了使前置后置的重载版本无法区分,后置版本接受一个额外不被使用的int类型的形参
//当我们使用后置运算符时,编译器为这个形参提供一个值为0的实参
StrBlobPtr& operator++(int);
StrBlobPtr& operator--(int);
private:
std::shared_ptr<std::vector<std::string>>check(std::size_t, const std::string&)const;
std::weak_ptr<std::vector<std::string>>wptr;
std::size_t curr;
};
//前置版本
StrBlobPtr& StrBlobPtr::operator++()
{
//检查,如果curr已经指向容器的尾后位置,则无法递增它
check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
StrBlobPtr& StrBlobPtr::operator--()
{
//检查,如果curr已经指向容器的首位置,则无法递减它
--curr;
check(curr, "decrement past begin of StrBlobPtr");
return *this;
}
//后置版本
StrBlobPtr& StrBlobPtr::operator++(int)
{
//在递增对象之前要记录对象的状态
//无需检查有效性,调用前置递增运算时才要检查
//记录当前的值
StrBlobPtr ret = *this;
//向后移动一个元素,前置++需要检查递增的有效性
++* this;
//返回之前记录的状态
return ret;
}
StrBlobPtr& StrBlobPtr::operator--(int)
{
//在递减对象之前要记录对象的状态
//无需检查有效性,调用前置递减运算时才要检查
//记录当前的值
StrBlobPtr ret = *this;
//向后移动一个元素,前置--需要检查递减的有效性
--* this;
//返回之前记录的状态
return ret;
}
练习14.28:
class StrBlobPtr
{
friend bool operator==(const StrBlobPtr&, const StrBlobPtr&);
friend bool operator!=(const StrBlobPtr&, const StrBlobPtr&);
friend bool operator<(const StrBlobPtr&, const StrBlobPtr&);
friend bool operator<=(const StrBlobPtr&, const StrBlobPtr&);
friend bool operator>(const StrBlobPtr&, const StrBlobPtr&);
friend bool operator>=(const StrBlobPtr&, const StrBlobPtr&);
//指针算术
friend StrBlobPtr operator+(const StrBlobPtr& sb, size_t n);
friend StrBlobPtr operator-(const StrBlobPtr& sb, size_t n);
public:
StrBlobPtr() : curr(0) { }
StrBlobPtr(StrBlob& a, size_t sz = 0) :wptr(a.data), curr(sz) { }
std::string& deref() const;
StrBlobPtr& incr();
//递增递减运算符
//前置版本
StrBlobPtr& operator++();
StrBlobPtr& operator--();
//后置版本,为了使前置后置的重载版本无法区分,后置版本接受一个额外不被使用的int类型的形参
//当我们使用后置运算符时,编译器为这个形参提供一个值为0的实参
StrBlobPtr& operator++(int);
StrBlobPtr& operator--(int);
private:
std::shared_ptr<std::vector<std::string>>check(std::size_t, const std::string&)const;
std::weak_ptr<std::vector<std::string>>wptr;
std::size_t curr;
};
//指针加法运算
StrBlobPtr operator+(const StrBlobPtr& sb, size_t n)
{
auto tmp_ret = sb;
tmp_ret.curr += n;
return tmp_ret;
}
//减法运算
StrBlobPtr operator-(const StrBlobPtr& sb, size_t n)
{
auto tmp_ret = sb;
tmp_ret.curr -= n;
return tmp_ret;
}
练习14.29:
递增递减运算符会改变对象的状态,所以不能定义为const版本