C++采用allocator模板仿造string

写在前言:这是一道C++primer第五版第十三章的习题,13.44,都是按自己的感觉写的,如有逻辑错误,请您不吝赐教!

进入正题:这个String支持标准库string的基础操作,比如+=操作、输出操作、size()函数、capacity()函数、begin()函数、end()函数。
从头分析,构造函数接受无参,也接受一个const char*的字符指针,ptr递增,指向str的尾部,相当于迭代器end()位置,调用alloac_begin_end函数,返回一个pair类型,first成员指向首,second成员指向尾。直接输出就调用<<重载函数,调用show()函数直接输出,如果进行+=操作,先判断容量的大小是否够新增的大小,如果不够,调用reallocat(),重新分配大小,用allocate重新构建,construct添加以前所保存的值,free()函数,释放之前所保留的内存空间。大致的思路就是这样的。

通过写这个String类,终于理解当初的困惑,destroy函数–first_free目的不是把first_free减到first的位置,而是为了销毁存储的元素,重新构建也和–first_frr减到first的位置无关,重建是用allocate重新分配大小,construct添加元素,进而完成重建。

#ifndef STRING_H_INCLUDED
#define STRING_H_INCLUDED
#include"dxgzg.h"
using std::allocator;
using std::cout;
using std::endl;
class String {
	friend std::ostream& operator<<( std::ostream&out,String& s);//重载输出运算符,参数顺序不能改变
	allocator<char>alloc;
	char* first, * first_free, *end1;
	void check_size(size_t num) {
		if (size()+num>= capacity()) {
			reallocat(num);
		}
	}
	
	std::pair<char*, char*>alloc_begin_end(const char *c1,const char *c2) {
		auto newdata = alloc.allocate(c2 - c1);
		return { newdata,std::uninitialized_copy(c1,c2,newdata) };//unitialized_copy返回值类似迭代器end的位置
	}
	void reallocat(size_t num) {
		size_t newcapacity =(capacity()!=0)?capacity()* 2+num:10;
		auto newfirst = alloc.allocate(newcapacity);
		auto newfirst_free = newfirst;
		auto f = first;
		for (auto it = begin(); it != end(); ++it) {
			alloc.construct(newfirst_free++, *it);
		}
		free();//释放原先所指向的地址
		first = newfirst;
		first_free = newfirst_free;
		end1 = first + newcapacity;
	}
public:
	
	String():first(nullptr),first_free(nullptr),end1(nullptr){}
	String(const char *str) {
		auto ptr = str;
		while (*ptr!='\0') {//这样求出char*的字符串长度
			++ptr;
		}
		auto pair_it = alloc_begin_end(str,ptr);
		first = pair_it.first;
		first_free = end1 = pair_it.second;
	}
	
	String(const String& s) {//this需要重新用allocate构建
		auto newdata = alloc_begin_end(s.begin(), s.end());
		this->first = newdata.first;
		this->first_free = this->end1 = newdata.second;
	}
	
	String& operator=(const String& s) {
		free();
		auto newdata = alloc_begin_end(s.begin(), s.end());
		this->first = newdata.first;
		this->first_free = this->end1 = newdata.second;
		return *this;
	}
	
	String& operator+=(const String &str) {
		size_t num = str.size();
		check_size(num);
		for (auto it = str.begin(); it != str.end();++it) {
			alloc.construct(this->first_free++,*it);
		}
		return *this;
	}
	
	~String() {
		free();
	}
	
	void free() {
		if (first) {
			for (auto f = first_free; f != first;) {
				alloc.destroy(--f);
			}
			alloc.deallocate(first,end1-first);
		}
	}
	
	void show(){
		for (auto it = begin(); it != end(); ++it) {
			cout << *it;
		}
	}
	
	char* begin()const{
		return first;
	}
	
	char* end()const{
		return first_free;
	}
	
	size_t size()const{
		return first_free - first;
	}
	
	size_t capacity()const{
		return end1 - first;
	}

};
std::ostream& operator<<(std::ostream&out,String&s) {
		s.show();
		return out;
}
#endif // !STRING_H_INCLUDED

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值