C++ primer 5th 实现Blob及其伴随类的模板

C++ primer 5th 课后练习
熟悉模板的编写
将之前的StrBlob及其伴随类改写成模板 支持多种类型
其中Blob的数据成员是shared_ptr<vector> 多个对象共享一个vetor<T> 支持一些基于vector<T>的操作
BlobPtr和ConstBlobPtr分别是Blob的非常量、常量的自定义迭代器

//16.12 16.13 编写自己版本的Blob和BlobPtr模板 并为BlobPtr的相等和关系运算符选择合适的友好关系类型

//声明 重载operator和在Blob中声明友元时用到
template<typename> class Blob;
template<typename> class BlobPtr;
template<typename> class ConstBlobPtr;


//==============================================================================
//
//  Blob - custom vector
//
//==============================================================================

//.h
//二元运算符要根据不同模板实参类型分别定义 因此需要用到和Blob(Ptr,consPtr)相同的模板实参 使用模板实参就需要在前面声明模板实参
//前置声明 在BlobPtr中声明友元所需要的
template<typename T> bool operator==(const Blob<T>&,const Blob<T>&);
template<typename T> bool operator!=(const Blob<T>&,const Blob<T>&);
template<typename T> bool operator< (const Blob<T>&,const Blob<T>&);
template<typename T> bool operator<=(const Blob<T>&,const Blob<T>&);
template<typename T> bool operator> (const Blob<T>&,const Blob<T>&);
template<typename T> bool operator>=(const Blob<T>&,const Blob<T>&);
template<typename T> class Blob {
   
	//注:类内作用域 使用模板时 可以省略模板参数列表 但是在类外定义或声明时必须加上模板参数列表 template<typename T>
	friend class BlobPtr<T>;
	friend class ConstBlobPtr<T>;
	//注:类模板中 将运算符重载函数声明为友元时 必须在运算符后跟上模板实参<T>
	friend bool operator==<T>(const Blob<T>&, const Blob<T>&);
	friend bool operator!=<T>(const Blob<T>&, const Blob<T>&);
	friend bool operator< <T>(const Blob<T>&, const Blob<T>&);
	friend bool operator<=<T>(const Blob<T>&, const Blob<T>&);
	friend bool operator> <T>(const Blob<T>&, const Blob<T>&);
	friend bool operator>=<T>(const Blob<T>&, const Blob<T>&);
public:
	using size_type = typename vector<T>::size_type;

	Blob() :data(make_shared<vector<T>>()) {
    }//构造一个新的shared_ptr
	Blob(initializer_list<T> il):data(make_shared<vector<T>>(il)){
    }
	Blob(const Blob<T>& blob) :data(blob.data){
    }
	Blob(const Blob<T>&& blob)noexcept :data(std::move(blob.data)){
    }//移动构造函数
	Blob& operator=(const Blob<T>&);
	Blob& operator=(Blob<T>&&) noexcept;//移动赋值运算符

	T& operator[](size_t n) ;//注 容器大小类型一般使用size_type 下标一般使用size_t
	const T& operator[](size_t n) const;

	size_type size()const {
   
		return data->size();
	}
	bool empty() const {
   
		return data->empty();
	}

	void push_back(const T& t) {
   
		data->push_back(t);
	}
	void push_back(const T&& t) {
   
			data->push_back(std::move(t));
		}

	void pop_back();
	T& front();
	const T& front() const;
	T& back();
	const T& back() const;

	BlobPtr<T> begin();
	BlobPtr<T> end();
	ConstBlobPtr<T> cbegin() const;
	ConstBlobPtr<T> cend() const;

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

//.cpp
//------------------------------------------------------------------------------
//  friend function.
//------------------------------------------------------------------------------
template<typename T> bool operator==(const Blob<T>& lhs,const Blob<T>& rhs) {
   
	return *lhs.data == *rhs.data;
}
template<typename T> bool operator!=(const Blob<T>& lhs,const Blob<T>& rhs) {
   
	return !(lhs == rhs);
}
template<typename T> bool operator<(const Blob<T>& lhs,const Blob<T>& rhs) {
   
	//小于符号重载使用标准库函数lexicographical_compare比较 按字典序列比较两个列表
	return lexicographical_compare(lhs.data->begin(),lhs.data->end(),rhs.data->begin(),rhs.data->end());
}
template<typename T> bool operator>(const Blob<T>& lhs,const Blob<T>& rhs) {
   
	return rhs<lhs;
}
template<typename T> bool operator<=(const Blob<
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值