StrBlobPtr算术运算符的实现

简介

参见C++primer第十四章第六节的习题


类说明

这个类是一个指向StrBlob类的指针,只不过不同于普通指针,该类的数据成员有一个weak_ptr,在构造函数中,我们将该指针指向shared_ptr指向的内容,不过该指针并不会像shared_ptr那样,为use_count加一。
由于 weak_ptr 所指向的对象可能不存在,因此使用了一个 check() 来检查该类在进行操作前的合法性,在该函数中,我们用到了 lock() 函数用来检验,如果存在,则返回一个指向该对象的 shared_ptr 指针,否则报错。
关于算术运算符,我起初定义的是非成员函数,但是该类的算术运算符并不需要如此,原因是我们并不会对两个指针做加法,这样没有意义,我们只会对指针做偏移,所以该算术运算符就相当于是++,–的一个扩大版而已。与非成员函数一样,我们同样利用复合运算符来实现算术运算符。
下面是代码:


/*
===========================================================================

C++ Primer 5th Exercise Answer Source Code

StrBlob, StrBlobPtr

If you have questions, try to connect with me: pence<1477364283@qq.com>

===========================================================================
*/

#pragma once

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <memory>
#include <algorithm>
#include <utility>
#include "StrVec.h"

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::istringstream;
using std::ostringstream;
using std::map;
using std::set;
using std::ifstream;
using std::getline;
using std::shared_ptr;
using std::size_t;

class StrBlobPtr;

class StrBlob
{
public:
	friend class StrBlobPtr;
	friend bool operator==(const StrBlob&, const StrBlob&);
	friend bool operator!=(const StrBlob&, const StrBlob&);
	friend bool operator<(const StrBlob&, const StrBlob&);
	friend bool operator>(const StrBlob&, const StrBlob&);
	friend bool operator<=(const StrBlob&, const StrBlob&);
	friend bool operator>=(const StrBlob&, const StrBlob&);

	using size_type = vector<string>::size_type;
	/*构造函数*/
	StrBlob();			//默认构造函数
	StrBlob(std::initializer_list<string> list);

	/*拷贝构造函数*/
	StrBlob(const StrBlob& rCopy):data(std::make_shared<vector<string>>(*rCopy.data)){}

	/*拷贝赋值运算符*/
	StrBlob& operator= (const StrBlob & rCopy)
	{
		data = std::make_shared<vector<string>>(*rCopy.data);
		return *this;
	}

	/*重载下标运算符*/
	string& operator[](std::size_t n)
	{
		check("out of range", n);
		return (*data)[n];
	}
	const string& operator[](std::size_t n) const
	{
		check("out of range", n);
		return (*data)[n];
	}

	/*成员函数*/
	bool empty() { return data->empty(); }
	void push_back(const string& str) { data->push_back(str); }
	void pop_back();
	StrBlobPtr begin(); 
	StrBlobPtr end();

	size_type size() { return data->size(); }
	string& front();
	string& back();
	const string& front() const;
	const string& back() const;
	unsigned count() const { return data.use_count(); }

private:
	shared_ptr<vector<string>> data;
	void check(const string& wmsg, size_type idx) const;
};

class StrBlobPtr
{
public:
	friend bool operator==(const StrBlobPtr&, const StrBlobPtr&);
	friend bool operator!=(const StrBlobPtr& lhs, const StrBlobPtr& rhs);
	friend bool operator<(const StrBlobPtr& lhs, const StrBlobPtr& rhs);
	friend bool operator>(const StrBlobPtr& lhs, const StrBlobPtr& rhs);
	friend bool operator<=(const StrBlobPtr&, const StrBlobPtr&);
	friend bool operator>=(const StrBlobPtr&, const StrBlobPtr&);

	/*constructor*/
	StrBlobPtr() = default;
	StrBlobPtr(StrBlob& DataSource, size_t curr = 0) : pData(DataSource.data), idx(curr) {}


	/*subscript operator*/
	string& operator[](std::size_t n);
	const string& operator[](std::size_t n) const;

	/*increment decrement operator*/
	StrBlobPtr& operator++();
	StrBlobPtr& operator--();
	StrBlobPtr operator++(int);
	StrBlobPtr operator--(int);
	StrBlobPtr operator+(size_t) const;	
	StrBlobPtr operator-(size_t) const;
	StrBlobPtr& operator+=(size_t);
	StrBlobPtr& operator-=(size_t);


	/*members*/
	StrBlobPtr& increase();
	string& deref() const;
	unsigned count() const { return pData.use_count(); }

private:
	shared_ptr<vector<string>> check(size_t index, const string& msg) const;
	std::weak_ptr<vector<string>> pData;
	size_t idx = 0;
};

/*StrBlobPtr subscript operator*/
inline string& StrBlobPtr::operator[](std::size_t n)
{
	auto sharedPvector = check(n, "the access is cross the border");
	return (*sharedPvector)[n];
}
inline const string& StrBlobPtr::operator[](std::size_t n) const
{
	auto sharedPvector = check(n, "the access is cross the border");
	return (*sharedPvector)[n];
}

/*increment, decrement operator*/
inline StrBlobPtr& StrBlobPtr::operator++()
{
	check(idx, "the increment past end of StrBlobPtr");
	++idx;
	return *this;
}
inline StrBlobPtr& StrBlobPtr::operator--()
{
	--idx;
	check(idx, "the decrement past begin of StrBlobPtr");
	return *this;
}
inline StrBlobPtr StrBlobPtr::operator++(int)
{
	StrBlobPtr ret = *this;
	++* this;
	return ret;
}
inline StrBlobPtr StrBlobPtr::operator--(int)
{
	StrBlobPtr ret = *this;
	--* this;
	return ret;
}

inline StrBlobPtr StrBlobPtr::operator+(size_t n) const
{
	StrBlobPtr tmp = *this;
	tmp += n;
	return tmp;
}

inline StrBlobPtr StrBlobPtr::operator-(size_t n) const
{
	StrBlobPtr tmp = *this;
	tmp -= n;
	return tmp;
}

inline StrBlobPtr& StrBlobPtr::operator+=(size_t n)
{
	idx += n;
	check(idx, "the access is out of range!");
	return *this;
}

inline StrBlobPtr& StrBlobPtr::operator-=(size_t n)
{
	idx -= n;
	check(idx, "the access is out of range!");
	return *this;
}


#include "StrBlob.h"

/****************************************
*										*
*class StrBlob							*
*										*
*****************************************/
StrBlob::StrBlob() :data(std::make_shared<vector<string>>()) {}
StrBlob::StrBlob(std::initializer_list<string> list) : data(std::make_shared<vector<string>>(list)) {}

/*overload operators*/
bool operator==(const StrBlob& lhs, const StrBlob& rhs)
{
	if (*lhs.data == *rhs.data)
	{
		return true;
	}
	return false;
}
bool operator!=(const StrBlob& lhs, const StrBlob& rhs)
{
	return !(lhs == rhs);
}
bool operator<(const StrBlob& lhs, const StrBlob& rhs)
{
	return std::lexicographical_compare(lhs.data->begin(), lhs.data->end(), rhs.data->begin(), rhs.data->begin());
	
}//return *lhs.data < *rhs.data;
bool operator>(const StrBlob& lhs, const StrBlob& rhs)
{
	return rhs < lhs;
}
bool operator<=(const StrBlob& lhs, const StrBlob& rhs)
{
	return !(lhs > rhs);
}
bool operator>=(const StrBlob& lhs, const StrBlob& rhs)
{
	return !(lhs < rhs);
}

void StrBlob::check(const string& wmsg, size_type idx) const
{
	if (idx >= data->size())
	{
		throw std::out_of_range(wmsg);
	}
}

const string& StrBlob::back() const
{
	//this指针为一个指向const对象的常量指针,形如 const int* const p,因此当p想转换为非底层const的指针时,是不允许的
	//所以也需要为check定义const版本
	check("back on empty vector", 0);
	return data->back();
}

const string& StrBlob::front() const
{
	check("front on empty vector", 0);
	return data->front();
}

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

string& StrBlob::front()
{
	check("front on empty vector", 0);
	return data->front();
}

void StrBlob::pop_back()
{
	check("pop_back on empty vector", 0);
	return data->pop_back();
}

StrBlobPtr StrBlob::begin()
{
	return StrBlobPtr(*this);
}

StrBlobPtr StrBlob::end()
{
	return StrBlobPtr(*this, size());
}


/****************************************
*										*
*class StrBlobPtr						*
*										*
*****************************************/

/*overload operators*/
bool operator!=(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{
	if (lhs.idx != rhs.idx)
	{
		return true;
	}
	return false;
}
bool operator==(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{
	return !(lhs != rhs);
}
bool operator>(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{
	return lhs.idx > rhs.idx;
}
bool operator<(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{
	return lhs.idx < rhs.idx;
}
bool operator<=(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{
	return lhs.idx <= rhs.idx;
}
bool operator>=(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{
	return lhs.idx >= rhs.idx;
}

shared_ptr<vector<string>> StrBlobPtr::check(size_t index, const string& msg) const
{
	auto sData = pData.lock();
	if (!sData)
	{
		throw std::runtime_error("unbound StrBlobPtr");
	}
	else if (sData->size() <= index)
	{
		throw std::out_of_range(msg);
	}
	return sData;
}

StrBlobPtr& StrBlobPtr::increase()
{
	check(idx, "operating cross-border");
	++idx;
	return *this;
}

string& StrBlobPtr::deref() const
{
	auto sData = check(idx, "the deref is cross-border");
	return (*sData)[idx];
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值